﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO.Ports;
using System.Windows.Forms;
using MQTTnet;
using MQTTnet.Client;
using System.Threading;
using System.IO;
using NPOI.SS.UserModel;
using MQTTnet.Protocol;
using System.Windows.Forms.DataVisualization.Charting;
using System.Drawing;
using System.Net.Sockets;
using System.Net;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;
using TextBox = System.Windows.Forms.TextBox;
using System.Timers;
using NPOI.Util;
using NPOI.SS.Formula.Functions;
using CAPTS_Suite;
using preprocess;
using static System.Windows.Forms.VisualStyles.VisualStyleElement.Button;
using System.Diagnostics;
using MaterialSkin.Controls;
using System.Security.Cryptography;
using NPOI.XSSF.Streaming.Values;
using System.Diagnostics.Eventing.Reader;
using System.Runtime.Remoting.Channels;
using System.Management;
namespace CAPTS
{
	public partial class CAPTS_Borker
	{
        public SerialPort serialPort1 = null;
		public static MqttFactory mqttFactory;//创建MQTT类名称
		public static IMqttClient mqttClient;//创建客户端名称
		public string[] Setting_data = null;
		public static string payload_7810data = "";
		public static string payload_7820data = "";
		public static string LI_CO2="0";//LICOR7810 CO2
		public static string LI_H2O="0";//LICOR7810 H2O
		public static string LI_N2O="0";//LICOR7810 N2O
		public static string LI_CH4="0";//LICOR7810 CH4
		public string filePath = @"D:\\CAPTS_data\";


		public static int caseIndex = 1;//测量箱数目索引
        public static int currentLoop = 1;//j记录当前循环次数

        const int Master_Port= 16;//定义主机端口数
        const int Sum_Port = 32;//定义主机端口数
        public static int Master_Number = 16;
        public static int Slave_Number = 16;
		public static int caseNumber = 16;//设置的测量箱数
		public static int LoopCount=4;//循环次数（完成一轮操作为1次循环）
        public static int T1 = 30;   //单次抽气时间（单个箱子之间间隔时间）
        public static int T2 = 490;	//抽气间隔时间（所有箱子完成一轮操作后的间隔时间）
        public static int T3 = 1990; //循环间隔时间（整体功能完成的时间）
        public static int MasterToSlave = 1;//主机连接分机的端口
        public static int CaseNumForZeroing = 0;
		public static bool AnalyzerType = false;//true为SBA分析器，False为外接分析器
		public static string AnalyzerModel = "LICOR"; //LICOR: LICOR 7810 and 7820 分析器. PICARRO: PICARRO 分析器

        public static bool SBA5zeroTriggered = false;
		public int ZeroingTime = 0;


        public const string Address1 = "a";
        public const string Address2 = "b";
        public const string Address = "z";//广播
        const string Endflag = "\n";
        public static bool slave_connect = false;//是否连接从机
        public static bool slave_runflag=false;//从机启动标志
        public static bool master_runflag = false;//主机启动标志
        const int First_Srart_Zero = 0;
        const int Start = 1;
        const int CLOSE_ONE_CASE = 2; // 密闭1个箱子同时开通该箱子的气路
        const int OPEN_LAST_CLOSE_NEXT = 3; // 打开上一个测量箱子，并且密闭当前测量想
        const int OPEN_EXTRA_TUBE = 4; // 打开防堵气路，关闭测量气路
        const int SD_STATUS_STORE_TAIL = 5;
        const int SAVE_DATA = 6; // 保存数据
        const int Only_One = 7; //只循环一次
        const int Dry_CH = 8;//干燥
        const int Dry_MasterToSlave = 9;
        const int Wait = 10;
        const int Dry_One = 11;
        const int Wait_Dry = 12;
        const int SD_STATUS_WAIT_FOR_SBA5ZERO =13;
        public static bool LoopSate = true;//true为运行状态，false为暂停状态
		public static string Pro_State = null;
		public static string SysParameter = @"c://Debug/Parameter.txt";//系统参数默认文件
		public static int FlowLowTimes = 0;
        public static bool calibrate_state = false;  //校准标志
        public static bool cycleflag = false; //每次大循环结束，拟合标志
        public static Dictionary<string, Dictionary<string, double>> new_fiting_data = new Dictionary<string, Dictionary<string, double>>();//存放循环测量后拟合数据并显示
        public bool thread_falg = true;
        public static bool shown_flag = false;
        public  static string[] str_mcu;
        public static string stc_mcu14;
        public static string stc_mcu14_slave;
        public static int casein = 0;//用于访问数组，数组下标从0开始
        public static double Set_temperature;
        public static double Set_air_pressure;
        public static bool checkBox1_flag;
        public static DateTime _startTime; // 数据采集开始时间,防止第二天新建文本写入数据
        public static bool Measure_flag;//一次测量结束标志位
        //OneMeasurementData omd = new OneMeasurementData(caseNumber); // 需要考虑可能caseNumber改变后 可能 不会改变这里的设置
        //List<OneChamber> chamberList;
        private DataLine avgData = new DataLine();
        FileStream fileStream;
		StreamWriter streamWriter;
		public static string BakeData="";
		public CAPTS_Borker()
		{

		}
        public int convertTime2sec(string timeStr)
        {  //GOOD
           // format of timeStr is: 00:01:43
            if (timeStr.Length == 8)
            {
                int hour = int.Parse(timeStr.Substring(0, 2));
                int minute = int.Parse(timeStr.Substring(3, 2));
                int second = int.Parse(timeStr.Substring(6, 2));
                if (hour >= 0 && hour <= 24 && minute >= 0 && minute < 60 && second >= 0 && second < 60)
                { // check the data is a right time format. 
                    int timeSec = hour * 3600 + minute * 60 + second;
                    return timeSec;
                }
                else
                { // the data format is wrong, or the data is not a time. 
                    return -1;
                }

            }
            else
            {  // not the right format. 
                return -1;
            }

        }

        private string AutoDetectPort()
        {
            using (var searcher = new ManagementObjectSearcher("SELECT * FROM Win32_PnPEntity WHERE Name LIKE '%(COM%)'"))
            {
                foreach (var device in searcher.Get())
                {
                    string name = device["Name"]?.ToString();
                    if (name != null)
                    {
                        int start = name.LastIndexOf("(COM");
                        if (start > 0)
                        {
                            string port = name.Substring(start).Replace("(", "").Replace(")", ""); // 提取 COM口

                            if (name.Contains("CH341")|| name.Contains("CH340"))
                            {
                                return port;
                            }
                        }
                    }
                }
            }

            throw new Exception("未检测到CH341 模块串口！");
        }
        public bool connectSingleChip(string Port = null) // MCU and PC connect
        {
            string[] ports = SerialPort.GetPortNames();
            if (ports.Length == 0)
            {
                MessageBox.Show("Error: No serial ports available!");
                return false;
            }

            // 自动选择最后一个检测到的串口
            string portName = Port ?? AutoDetectPort();

            serialPort1 = new SerialPort(portName, 115200)
            {
                DataBits = 8,
                StopBits = StopBits.One,
                Parity = Parity.None
            };

            try
            {
                serialPort1.Open();
                serialPort1.DataReceived += getDataFromSingleChip;
                Pro_State = "Serial Open !!!";
                return true;
            }
            catch (Exception ex)
            {
                MessageBox.Show($"MCU connection failed: {ex.Message}");
                return false;
            }
        }


        public bool DisconncetSingleChip() //关闭串口
		{
			if (serialPort1.IsOpen)
			{
				serialPort1.Close();
				//serialPort1.Dispose();
				return true;
			}
			else
			{
				//MessageBox.Show("Warn: Serial Closed!");
				return false;
			}
		}
		
		public static async Task DisconnectLI7810()//7810与7820断开连接断开连接
		{
			/*
			 * This sample disconnects from the server with sending a DISCONNECT packet.
			 * This way of disconnecting is treated as a clean disconnect which will not
			 * trigger sending the last will etc.
			 */
			var mqttClientDisconnectOptions = mqttFactory.CreateClientDisconnectOptionsBuilder().Build();//这行代码觉得有问题

			await mqttClient.DisconnectAsync(mqttClientDisconnectOptions, CancellationToken.None);

			MessageBox.Show("The MQTT client is Disconnected.");
		}
		
		public bool caliSingleChipSensors(string str, TextBox textBox1, TextBox textBox2, TextBox textBox3, TextBox textBox4)
		//将校准的参数传到单片机上,,暂时不用这个参数
		{
			if (serialPort1.IsOpen)
			{
				if (textBox1.Text == null) { textBox1.Text = "0"; }
				if (textBox2.Text == null) { textBox2.Text = "0"; }
				if (textBox3.Text == null) { textBox3.Text = "0"; }
				if (textBox4.Text == null) { textBox4.Text = "0"; }
				string str2 = str + ":" + textBox1.Text + "," + textBox2.Text + "," + textBox3.Text + "," + textBox4.Text;
				serialPort1.Write(str2);
				return true;
			}
			else
			{
				//MessageBox.Show("Error: Serial closed!");
				return false;
			}

		}
        public void BroadCast(string str1, int port) //广播
        {
            string str = null;
            if (serialPort1.IsOpen)
            {
                string addr = Address;
                str = $"{addr}{str1}:{port}{Endflag}";
                BakeData = $"{str1}:{port}";
                serialPort1.Write(str); // 发送指令
                while (serialPort1.BytesToWrite > 0)
                {
                }

            }

        }
        public void Master_Command(string str1, int port) //单独主机，不涉及到主从机地址选择
        {
            string str = null;
            if (serialPort1.IsOpen)
            {
                string addr = null;
                addr = Address1;
                str = $"{addr}{str1}:{port}{Endflag}";
                BakeData = $"{str1}:{port}";
                serialPort1.Write(str); // 发送指令'
                while (serialPort1.BytesToWrite > 0)
                {
                }
            }
        }
        public void Slave_Command(string str1, int port) //单独控制从机干燥
        {
            string str = null;
            if (serialPort1.IsOpen)
            {
                string addr = Address2;
                str = $"{addr}{str1}:{port}{Endflag}";
                serialPort1.Write(str); // 发送指令
                BakeData = $"{str1}:{port}";
                while (serialPort1.BytesToWrite > 0)
                {
                }
            }
        }
        public void Set_Pump(string str1, int port, string add) //开关气泵，涉及到主从机选择，add为地址
        {
            string str = null;
            if (serialPort1.IsOpen)
            {
                string addr = add;
                str = $"{addr}{str1}:{port}{Endflag}";
                serialPort1.Write(str); // 发送指令
                BakeData = $"{str1}:{port}";
                while (serialPort1.BytesToWrite > 0)
                {
                }
            }
        }

        public string Send_Command(string str1, int port) // 打开或关闭测量箱及0-5V开关控制
        {
            string str = null;
            string ba;
            if (serialPort1.IsOpen)
            {
                string addr = null;
                if (port <= Master_Port)//可改为变量，从界面分别设置主从机数量
                {
                    addr = Address1; // 地址1对应1-16号箱体
                }
                else if (port <= Sum_Port)
                {
                    addr = Address2; // 地址2对应17-32号箱体
                    port = port - Master_Port; // 将从机箱体映射到1-16
                }
                if (port > 9)
                    {
                        char[] hexMap = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I' };
                        int index = (int)port - 10;
                        ba = hexMap[index].ToString();
                        BakeData = $"{str1}:{ba}";
                        if (index >= 0 && index < hexMap.Length)
                        {
                            str = $"{addr}{str1}:{hexMap[index]}{Endflag}";
                        }
                    }
                else
                {
                    str = $"{addr}{str1}:{port}{Endflag}";
                    BakeData = $"{str1}:{port}";
                }

                serialPort1.Write(str); // 发送指令
                Console.WriteLine(str);
                while (serialPort1.BytesToWrite > 0)
                {
                }
                return port.ToString();
            }
            else
            {
                Console.WriteLine("Error: Serial port is closed!");
                return null;
            }
        }

        public void setGasLid_Chamber(string str1, int a, int b) // 异步控制箱体和气路，KZ:1,2
        {
            string str = null;
            string ba;
            if (serialPort1.IsOpen)
            {
                string addr = null;
                if (a <= Master_Port)
                {
                    addr = Address1; // 地址1对应1-16号箱体
                }
                else if (a <=  Sum_Port)
                {
                    addr = Address2; // 地址2对应17-32号箱体
                }

                if (a > Master_Port)
                {
                    a = a - Master_Port; // 将从机箱体映射到1-16
                }
                if (b > Master_Port)
                { b = b - Master_Port; }
                else
                {
                    if (a > Master_Number)
                    {
                        a = a - Master_Number; // 将从机箱体映射到1-16
                    }
                    if (b > Master_Number)
                    { b = b - Master_Number; }
                }
                if (a <= 9 && b > 9)
                {
                    char[] hexMap = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I' };
                    int index_b = (int)b - 10;
                    ba = a.ToString();
                    if (index_b >= 0 && index_b < hexMap.Length)
                    {
                        str = $"{addr}{str1}:{a}{hexMap[index_b]}{Endflag}";
                    }
                }
                else if (a > 9 && b > 9)
                {
                    char[] hexMap = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I' };
                    int index_a = (int)a - 10;
                    int index_b = (int)b - 10;
                    ba = hexMap[index_a].ToString();
                    if (index_a < hexMap.Length && index_b < hexMap.Length)
                    {
                        str = $"{addr}{str1}:{hexMap[index_a]}{hexMap[index_b]}{Endflag}";
                    }
                }
                else if (a > 9 && b <= 9)
                {
                    char[] hexMap = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I' };
                    int index_a = (int)a - 10;
                    ba = hexMap[index_a].ToString();
                    if (index_a >= 0 && index_a < hexMap.Length)
                    {
                        str = $"{addr}{str1}:{hexMap[index_a]}{b}{Endflag}";
                    }
                }
                else
                {
                    str = $"{addr}{str1}:{a}{b}{Endflag}";
                    ba = a.ToString();
                }

                BakeData = $"{str1}:{ba}";
                serialPort1.Write(str); // 发送指令
                while (serialPort1.BytesToWrite > 0)
                {
                }
                Console.WriteLine(str);
            }
        }
        public bool statusFlag(string str) //控制MCU打开、关闭、暂停、调零、保存、发送校准参数
		{
			if (serialPort1.IsOpen)
			{
				serialPort1.Write(str);
				return true;
			}
			else
			{
				MessageBox.Show("Error: Serial closed!");
				return false;
			}
		}
		public void disposeConnect() //释放网口资源
		{
			if (mqttClient.IsConnected)
			{
				mqttClient.Dispose();
			}
			else 
			{
				return;
			}
		}
		public void Compare(string a, string b)
		{
			if (a != b)
			{
				serialPort1.Write(b);
			}
			else
				return;
		}
		public static void getDataForm7820(string str) 
		{
			string[] str1 = str.Split(',');
			for (int i = 0; i < str1.Length; i++)
			{
				if (str1[i].Contains("N2O"))
				{
					string[] str2 = str1[i].Split(':');
					if (str2[1] == "null" || str1[i].Contains("e"))
					{
						LI_N2O = "0";
					}
					else
					{
						LI_N2O = (Math.Round((Convert.ToDouble(str2[1])), 2)).ToString();//保留两位小数
                    }
					//Console.WriteLine(LI_N2O);
				}
				//7810也有H2O
				//if (str1[i].Contains("H2O"))
				//{
				//    string[] str2 = str1[i].Split(':');
				//    LI_H2O = str2[1];
				//    Console.WriteLine(LI_H2O);
				//}
			}
		}
		public static void getDataForm7810(string str) 
		{
			string[] str1 = str.Split(',');
			for (int i=0;i<str1.Length;i++) 
			{
				if (str1[i].Contains("H2O"))
				{
					string[] str2 = str1[i].Split(':');
					if (str2[1] == "null" || str1[i].Contains("e"))
					{
						LI_H2O = "0";
					}
					else
					{
						LI_H2O = (Math.Round((Convert.ToDouble(str2[1])), 2)).ToString();//保留两位小数
                    }
					//Console.WriteLine(LI_H2O);
				}
				else if (str1[i].Contains("CH4"))
				{
					string[] str2 = str1[i].Split(':');
					if (str2[1] == "null" || str1[i].Contains("e"))
					{
						LI_CH4 = "0";
					}
					else
					{
						//LI_CH4 = Convert.ToDouble(str2[1]).ToString("N2");
						LI_CH4 =  (Math.Round((Convert.ToDouble(str2[1])), 2)).ToString();

                    }
					//Console.WriteLine(LI_CH4);
				}
				else if (str1[i].Contains("CO2"))
				{
					string[] str2 = str1[i].Split(':');
					if (str2[1] == "null" || str1[i].Contains("e"))
					{
						LI_CO2 = "0";
					}
					else
					{
						LI_CO2 = (Math.Round((Convert.ToDouble(str2[1])), 2)).ToString();
                    }
					//Console.WriteLine(LI_CO2);
				}
				else 
				{

				}
			   
			}
		}
		public void getDataFromSingleChip(object sender, SerialDataReceivedEventArgs e)//获得MCU的数据
        {
            try//捕获serialPort1.Open();的异常，单片机断电时检测不到串口会报错
            {    
                string str = serialPort1.ReadTo("\n");
                //string str =serialPort1.ReadLine();
                Form1.lastDataReceivedTime = DateTime.Now;//记录当前接收到数据的时间
                Form1.serial_test_dis = str;
                serialPort1.DiscardInBuffer();
                //string[] str2 = str.Split('\t');
                str_mcu = str.Split('\t');
                if (str_mcu.Length == 16)
                {
                    stc_mcu14 = str_mcu[14];
                    if (str_mcu[15] == Address2)//收到从机的应答信号
                    {
                        stc_mcu14_slave = str_mcu[14];
                        serialPort1.Write(Address1 + "KK:1\n");//打开主机发送,关闭从机发送
                    }
                    //Console.WriteLine(BakeData);
                    if (str_mcu[15] == Address1)
                    {
                        double co2_uV = Form1.Device_Flag.Equals("3") ? Convert.ToDouble(str_mcu[1]) : 0.0;
                        double co2 = Form1.Device_Flag.Equals("3") ? Convert.ToDouble(str_mcu[2]) : 0.0;
                        double h2o_uV = Form1.Device_Flag.Equals("3") ? Convert.ToDouble(str_mcu[3]) : 0.0;
                        double h2o = Form1.Device_Flag.Equals("3") ? Convert.ToDouble(str_mcu[4]) : 0.0;

                        ChipPackages.C_CO2_uV = co2_uV.ToString();
                        ChipPackages.C_CO2 = co2.ToString();
                        ChipPackages.C_H2O_uV = h2o_uV.ToString();
                        ChipPackages.C_H2O = h2o.ToString();

                        ChipPackages.C_PPFD_uV = Convert.ToDouble(str_mcu[11]).ToString();
                        if ((Convert.ToInt32(str_mcu[12]) != 357 && Convert.ToInt32(str_mcu[12]) != 2006) )
                        {
                            ChipPackages.C_PPFD = Convert.ToInt32(str_mcu[12]) == 19|| Convert.ToInt32(str_mcu[12]) == 2005 || Convert.ToInt32(str_mcu[12]) == 2004 || Convert.ToInt32(str_mcu[12]) == 356  ? "0" : Convert.ToDouble(str_mcu[12]).ToString("N0");
                        }
                        else
                        {
                            ChipPackages.C_PPFD = "0";
                        }
                        ChipPackages.C_PA_uV = Convert.ToDouble(str_mcu[7]).ToString();
                        ChipPackages.C_PA = Convert.ToDouble(str_mcu[8]).ToString("N1");
                        ChipPackages.C_T_uV = Convert.ToDouble(str_mcu[9]).ToString();
                        //新增
                        ChipPackages.C_T = (((Convert.ToDouble(str_mcu[9]) / 1000000.0) * 120.0 - 40.0)).ToString("N1");//量程 -40到80
                        //ChipPackages.C_T = Convert.ToDouble(str_mcu[10]).ToString("N1");
                        ChipPackages.C_HR_uV = Convert.ToDouble(str_mcu[5]).ToString();
                        ChipPackages.C_HR = Convert.ToDouble(str_mcu[6]).ToString("N1");
                        ChipPackages.C_FLOW = Convert.ToDouble(str_mcu[13]).ToString();
 
                        // 若选择使用校准程序，则根据校准参数校准数据
                        if (calibrate_state == true)
                        {
                            if (Form1.Device_Flag.Equals("3"))
                            {
                                ChipPackages.C_CO2 = calibrate(co2, "CO2").ToString();
                                ChipPackages.C_H2O = calibrate(h2o, "H2O").ToString();
                            }
                            //新增
                            ChipPackages.C_T = ((((Convert.ToDouble(str_mcu[9]) / 1000000.0) * 120.0 - 40.0)).ToString("N1"));//量程 -40到80
                            //ChipPackages.C_T = calibrate(Convert.ToDouble(ChipPackages.C_T), "TEM").ToString();
                            ChipPackages.C_HR = calibrate(Convert.ToDouble(ChipPackages.C_HR), "RH").ToString();
                            ChipPackages.C_PA = calibrate(Convert.ToDouble(ChipPackages.C_PA), "PA").ToString();
                            ChipPackages.C_PPFD = calibrate(Convert.ToDouble(ChipPackages.C_PPFD), "PPFD").ToString();
                            if(Convert.ToInt32(ChipPackages.C_PPFD)<0)
                            {
                                ChipPackages.C_PPFD = "0";
                            }
                        }

                    }

                }

            }
            catch(Exception ex)
            {
                //Console.WriteLine("123"+ex.Message);
            }
	
		}

        public void checkDataReceiveTimeout(object sender, EventArgs e)
        {
		
            //Form1 form = new Form1();
            TimeSpan elapsed = DateTime.Now - Form1.lastDataReceivedTime;//计算等待时间
            if (elapsed.TotalSeconds > 60&& !Form1.isStoppedByUser)//超过120s未接收
            {
                // 如果超过了超时时间没有收到数据，则认为单片机已断电
                // 执行单片机关机的逻辑
                // 记录日志
                //form.button3_Click(null, EventArgs.Empty);
                if (!shown_flag)
				{ 
                    shown_flag = true;
					MessageBox.Show("主机连接已断开，请检查连接或重新启动主机");

                }
                try//捕获serialPort1.Open();的异常，单片机断电时检测不到串口会报错
                {
                    //while (!connectSingleChip()) ;
                    //form.button1_Click(null, EventArgs.Empty);//这里添加自动开始的代码（从头开始），不需要用户点击开始按钮
          
                }
                catch 
                {
                }
                
            }
        }

        //7810建立连接
        public static async Task Handle_Received_Application_Message()
		{
			/*
			 * This sample subscribes to a topic and processes the received message.
			 */
			var mqttFactory = new MqttFactory();
			var mqttClient = mqttFactory.CreateMqttClient();///不能用using 会将委托释放掉
			//var mqttClient2 = mqttFactory.CreateMqttClient();
			var mqttClientOptions = new MqttClientOptionsBuilder().WithTcpServer("169.254.68.1").Build();
			//var mqttClientOptions2 = new MqttClientOptionsBuilder().WithTcpServer("169.254.68.133").Build();
			// Setup message handling before connecting so that queued messages
			// are also handled properly. When there is no event handler attached all
			// received messages get lost.

			mqttClient.ApplicationMessageReceivedAsync += e =>
				{
					payload_7810data = string.Empty; //
					payload_7810data = e.ApplicationMessage.ConvertPayloadToString();
					//Console.WriteLine(payload_7810data);
					getDataForm7810(payload_7810data);
					return Task.CompletedTask;
				};
			//mqttClient2.ApplicationMessageReceivedAsync += e =>
			//{
			//    payload_7820data = string.Empty; //
			//    payload_7820data = e.ApplicationMessage.ConvertPayloadToString();
			//    Console.WriteLine(payload_7820data);
			//    getDataForm7820(payload_7820data);
			//    return Task.CompletedTask;
			//};

			await mqttClient.ConnectAsync(mqttClientOptions, CancellationToken.None);
			//await mqttClient2.ConnectAsync(mqttClientOptions2, CancellationToken.None);

			var mqttSubscribeOptions = mqttFactory.CreateSubscribeOptionsBuilder()
					.WithTopicFilter(
						f =>
						{
							f.WithTopic("licor/niobrara/output/concentration");
						})
					.Build();

			  var str2 = await mqttClient.SubscribeAsync("licor/niobrara/output/concentration");
			  //var str2_2 = await mqttClient2.SubscribeAsync("licor/niobrara/output/concentration");
		}
		//7820建立连接
		public static async Task Publish_Application_Message()//发布信息
		{
			var mqttFactory1 = new MqttFactory();
			var mqttClient2 = mqttFactory1.CreateMqttClient();
			var mqttClientOptions2 = new MqttClientOptionsBuilder().WithTcpServer("169.254.68.2").Build();
			mqttClient2.ApplicationMessageReceivedAsync += e =>
			{
				payload_7820data = string.Empty; //
				payload_7820data = e.ApplicationMessage.ConvertPayloadToString();
				//Console.WriteLine(payload_7820data);
				getDataForm7820(payload_7820data);
				return Task.CompletedTask;

			};
			await mqttClient2.ConnectAsync(mqttClientOptions2, CancellationToken.None);
			var mqttSubscribeOptions = mqttFactory1.CreateSubscribeOptionsBuilder()
				   .WithTopicFilter(
					   f =>
					   {
						   f.WithTopic("licor/niobrara/output/concentration");
					   })
				   .Build();
			var str2_2 = await mqttClient2.SubscribeAsync("licor/niobrara/output/concentration");
		}
		public bool getDataFromLI7810(string str,TextBox textBox) //订阅一条信息
		{
			if (mqttClient.IsConnected)
			{
				var mqttSubscribeOptions = mqttFactory.CreateSubscribeOptionsBuilder()
				  .WithTopicFilter(
					  f =>
					  {
						  f.WithTopic("licor/niobrara/system/shutdown");
					  })
				  .Build();

				mqttClient.SubscribeAsync(mqttSubscribeOptions, CancellationToken.None);

				Console.WriteLine("MQTT client subscribed to topic.");

				Console.WriteLine("Press enter to exit.");
				//Console.ReadLine();
				return true;
			}
			else
			{
				MessageBox.Show("Error: mqttClient Disconnected!");
				return false;
			}

		}
		public string mergeData(string AnalyzerModel)  // 气体分析器型号， LICOR 1， PICARRO 2
		{
			string str = null;
			if (AnalyzerModel.Equals("LICOR")){
                str = "'" + DateTime.Now.ToString("HH:mm:ss") +
                "\t" + ChipPackages.C_CO2_uV + "\t" + ChipPackages.C_CO2 +
                "\t" + ChipPackages.C_H2O_uV + "\t" + ChipPackages.C_H2O +
                "\t" + ChipPackages.C_HR_uV + "\t" + ChipPackages.C_HR +
                "\t" + ChipPackages.C_PA_uV + "\t" + ChipPackages.C_PA +
                "\t" + ChipPackages.C_T_uV + "\t" + ChipPackages.C_T +
                "\t" + ChipPackages.C_PPFD_uV + "\t" + ChipPackages.C_PPFD +
                "\t" + LI_CO2 + "\t" + LI_H2O + "\t" + LI_CH4 + "\t" + LI_N2O;
                //Console.WriteLine("选择LICOR" + CAPTS_Picarro.PI_CO2_dry);
            }
			else if (AnalyzerModel.Equals("PICARRO"))
			{
                str = "'" + DateTime.Now.ToString("HH:mm:ss") +
                "\t" + ChipPackages.C_CO2_uV + "\t" + ChipPackages.C_CO2 +
                "\t" + ChipPackages.C_H2O_uV + "\t" + ChipPackages.C_H2O +
                "\t" + ChipPackages.C_HR_uV + "\t" + ChipPackages.C_HR +
                "\t" + ChipPackages.C_PA_uV + "\t" + ChipPackages.C_PA +
                "\t" + ChipPackages.C_T_uV + "\t" + ChipPackages.C_T +
                "\t" + ChipPackages.C_PPFD_uV + "\t" + ChipPackages.C_PPFD +
                "\t" + CAPTS_Picarro.PI_CO2 + "\t" + CAPTS_Picarro.PI_CO2_dry + 
				"\t" + CAPTS_Picarro.PI_H2O + "\t" + CAPTS_Picarro.PI_CH4 + 
				"\t" + CAPTS_Picarro.PI_CH4_dry + "\t" + CAPTS_Picarro.PI_N2O + 
				"\t" + CAPTS_Picarro.PI_N2O_dry + "\t" + CAPTS_Picarro.PI_NH3;
                //Console.WriteLine("选择PICARRO" + CAPTS_Picarro.PI_CO2_dry);
            }
            else
            {
                str = "'" + DateTime.Now.ToString("HH:mm:ss") +
                "\t" + ChipPackages.C_CO2_uV + "\t" + ChipPackages.C_CO2 +
                "\t" + ChipPackages.C_H2O_uV + "\t" + ChipPackages.C_H2O +
                "\t" + ChipPackages.C_HR_uV + "\t" + ChipPackages.C_HR +
                "\t" + ChipPackages.C_PA_uV + "\t" + ChipPackages.C_PA +
                "\t" + ChipPackages.C_T_uV + " \t" + ChipPackages.C_T +
                "\t" + ChipPackages.C_PPFD_uV + "\t" + ChipPackages.C_PPFD;
            }
            Console.WriteLine(str);
            return str;
        }
		public bool saveData(string filePath1,string AnalyzerModel) //写入数据，此处可能需要建立委托
		{
			if (File.Exists(filePath1))
			{
				// FileStream fileStream = new FileStream(filePath1, FileMode.Append, FileAccess.Write);
				streamWriter = new StreamWriter(filePath1,true);
				streamWriter.WriteLine(mergeData(AnalyzerModel));
				streamWriter.Flush();
				streamWriter.Close();
				streamWriter.Dispose();
				return true;
			}
			else
			{
				MessageBox.Show("FilePath null");
				return false;
			}
		}
        public bool writeflag(string filePath1, string str) //写入标志位，此处可能需要建立委托
        {
            if (File.Exists(filePath1))
            {
                // FileStream fileStream = new FileStream(filePath1, FileMode.Append, FileAccess.Write);
                streamWriter = new StreamWriter(filePath1, true);
                streamWriter.WriteLine(str);
                streamWriter.Flush();
                streamWriter.Close();
                streamWriter.Dispose();
                return true;
            }
            else
            {
                MessageBox.Show("FilePath null");
                return false;
            }
        }
        public void WriteData(string filePath1,string str2,string str3) //写入数据，此处可能需要建立委托
		{
			string line;
		   // string line2;
		   // bool exit = false;
			int i ;

				StreamReader sr = new StreamReader(filePath1);
				line = sr.ReadToEnd();
				sr.Close();
				sr.Dispose();
				StreamWriter wr = new StreamWriter(filePath1);
				if (line!=null)
				{
				 string[] line2 = line.Split('\r');
				for (i=0;i<line2.Length;i++)
				{
					if (line2[i]!=null) 
					{
						if (line2[i].Contains("\n")) 
						{
						 line2[i] = line2[i].Remove(0,1);
						}
						if (line2[i].Contains(str2))
						{
							wr.WriteLine(str2 + str3);
						}
						else
						{
							wr.WriteLine(line2[i]);
						}
					}
				   
				}
				   
				}
				 wr.Flush();
				 wr.Close();
				 wr.Dispose();

		}
		public void ReadData()
		{
			using (StreamReader sr = new StreamReader(SysParameter))//需要加标定文件到指定文件夹
			{
				string line;

				// 从文件读取并显示行，直到文件的末尾 
				while ((line = sr.ReadLine()) != null)
				{
					if (line.StartsWith("K:"))
					{
						string[] str2 = line.Split(':');
						string[] str3 = str2[1].Split(',');
						T1 = Convert.ToInt32(str3[1]);//单次抽气时间
						T2 = Convert.ToInt32(str3[2]);//抽气间隔时间
						T3 = Convert.ToInt32(str3[3]);//循环间隔时间
                        LoopCount = Convert.ToInt32(str3[4]);//循环次数
                        Master_Number = Convert.ToInt32(str3[5]);//主机数
                        Slave_Number = Convert.ToInt32(str3[6]);//从机数
                        if (!slave_connect)//从机未连接
                        {
                            caseNumber = Convert.ToInt32(str3[5]);//箱子总数为主机箱子数
                        }
                        else
                            caseNumber = Convert.ToInt32(str3[0]);//设置的测量箱数
                    }
                    if (line.StartsWith("SLA:"))
                    {
                        string[] str1 = line.Split(':');
                        string[] str2 = str1[1].Split(',');
                        MasterToSlave = int.Parse(str2[0]);//将从机与主机连接端口读出
                    }
                    else
					{
						
					}

				}

			}


		}
		
		public string creatFile(int a) //创建文件或验证文件是否存在
		{
            //若E盘存在则存储至E盘CAPTS_data文件下，否则存储至D盘CAPTS_data文件下
            string Epath_3 = @"E:\CAPTS_data\";
            string str1 = "";
            if (Directory.Exists(Epath_3))
            {
                str1 = Epath_3 + a.ToString("00") + _startTime.ToString("yyMMdd") + ".txt";
            }
            else
            {
                str1 = filePath + a.ToString("00") + _startTime.ToString("yyMMdd") + ".txt";
            }

            if (File.Exists(str1))
			{
				//fileStream = new FileStream(str1, FileMode.Append, FileAccess.Write);
				//Console.WriteLine(str1);
                return str1;
			}
			else 
			{
				 fileStream = new FileStream(str1,FileMode.Create,FileAccess.Write);
				 fileStream.Flush();
				 fileStream.Close();
				 fileStream.Dispose();

				//StreamWriter streamWriter = new StreamWriter(fileStream);
				return str1;
			}
		}
		public void WriteTail(string str,string value) 
		{
			if (File.Exists(str))
			{
				Console.WriteLine(str);

                if (value.Equals("1"))
				{
                    streamWriter = new StreamWriter(str, true);
                    string str2 = "Time	CO2_1	CO2_1	H2O_1	H2O_1	H2O_2	H2O_2	AP	AP	T	T	PPF_2	PPF_2	LI_CO2	LI_H2O	LI_CH4	LI_N2O";  //v1.56
                    string str3 = "  	[uV]	[ppm]	[uV]	ppt	[uV]	[%]	[uV]	[KPa]	[uV]	[Cel]	[uV]	[umol]	ppm	ppm	ppb	ppb";  //v1.56
                    streamWriter.WriteLine(str2);
                    streamWriter.WriteLine(str3);
					streamWriter.Flush();
					streamWriter.Close();
					streamWriter.Dispose();
                }
				else if (value.Equals("2"))
				{
                    streamWriter = new StreamWriter(str, true);
                    //Console.WriteLine("正在创建Tail！");
                    string str2 = "Time	CO2_1	CO2_1	H2O_1	H2O_1	H2O_2	H2O_2	AP	AP	T	T	PPF_2	PPF_2	PI_CO2	PI_CO2_dry	PI_H2O	PI_CH4	PI_CH4_dry	PI_N2O	PI_N2O_dry	PI_NH3";  //v1.56
                    string str3 = "  	[uV]	[ppm]	[uV]	ppt	[uV]	[%]	[uV]	[KPa]	[uV]	[Cel]	[uV]	[umol]	ppm	ppm	ppm	ppb	ppb	ppb	ppb	ppb";  //v1.56
                    streamWriter.WriteLine(str2);
                    streamWriter.WriteLine(str3);
                    //streamWriter.Flush();
                    //Console.WriteLine("Tail 写入成功！");
                    streamWriter.Close();
                    streamWriter.Dispose();
                }
				else
                {
                    streamWriter = new StreamWriter(str, true);
                    string str2 = "Time	CO2_1	CO2_1	H2O_1	H2O_1	H2O_2	H2O_2	AP	AP	T	T	PPF_2	PPF_2";  //v1.56
                    string str3 = "  	[uV]	[ppm]	[uV]	ppt	[uV]	[%] [uV]	[KPa]	[uV]	[Cel]	[uV]	[umol]";  //v1.56
                    streamWriter.WriteLine(str2);
                    streamWriter.WriteLine(str3);
                    streamWriter.Flush();
                    streamWriter.Close();
                    streamWriter.Dispose();
                }
			}
			else
			{
				Console.WriteLine("Tail 已存在");
				MessageBox.Show("File Null !!!");
			}

		}
		public void disposeStream() //释放当前文件数据流
		{
			if (streamWriter != null) 
			{
                streamWriter.Close();
                streamWriter.Dispose();
            }
		}
        // 计算平均值和标准差的方法
        private (double mean, double stdDev) CalculateMeanAndStdDev(List<CAPTS_Suite.DataLine> dataLines, Func<CAPTS_Suite.DataLine, double> selector)
        {
            // 计算平均值
            double total = dataLines.Sum(selector);
            double mean = total / dataLines.Count;
            // 计算标准差
            double sumOfSquaredDifferences = dataLines.Sum(dl => Math.Pow(selector(dl) - mean, 2));
            double stdDev = Math.Sqrt(sumOfSquaredDifferences / dataLines.Count);

            return (mean, stdDev);
        }
        //超时检查
        public bool WaitForCondition(Func<bool> condition, int timeoutMilliseconds, Action resendAction)
        {
            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();

            int checkInterval = 500; // 每隔 500 毫秒检查一次
            int lastCheckTime = 0;

            while (condition())
            {
                if (stopwatch.ElapsedMilliseconds >= timeoutMilliseconds)
                {
                    return false; // 超时
                }

                if (stopwatch.ElapsedMilliseconds - lastCheckTime >= checkInterval)
                {
                    resendAction?.Invoke(); // 再发送一次串口数据
                    lastCheckTime = (int)stopwatch.ElapsedMilliseconds;
                }

                System.Threading.Thread.Sleep(10); // 可选的短暂延迟，防止高 CPU 占用
            }

            return true; // 条件满足
        }


        // 默认顺序的measureLoop函数，重载，默认顺序也需要提供箱子编号数组
        public void measureLoop(object parameter)
		{
			int[] chamberIDList = new int[caseNumber];
            int[] Master_array;
            //for (int k = 0; k < caseNumber; k++)
            //{
            //	chamberIDList[k] = k+1;
            //         }
            if (!slave_connect)
            {
                Master_array = new int[16];
                for (int k = 0; k < 16; k++)
                {
                    Master_array[k] = k + 1;
                }
                for (int i = 0; i < Master_Number; i++)
                {
                    chamberIDList[i] = Master_array[i];
                }
            }
            else 
            {
                Master_array = new int[15];//15有一个要空出来连接分机
                int ind = 0;
                for (int k = 0; k < 16; k++)
                {
                    if (k + 1 == MasterToSlave)
                    {
                        // 跳过 MasterToSlave 对应的数
                        continue;
                    }

                    Master_array[ind] = k + 1;  // 继续添加其他数
                    ind++;  // 增加索引
                }
                int[] Slave_array = new int[16];
                for (int j = 0; j < 16; j++)
                {
                    Slave_array[j] = j + 17;  // j从0开始，j + 17为17到32
                }
                for (int i = 0; i < Master_Number; i++)
                {
                    chamberIDList[i] = Master_array[i];
                }

                // 将Slave_array的前slaveNumber个元素复制到tb46
                for (int i = 0; i < Slave_Number; i++)
                {
                    chamberIDList[Master_Number + i] = Slave_array[i];
                }
            }
            if (parameter.Equals("3"))
            {
                SBA5_Measure(parameter, chamberIDList);
            }
            else
            { measureLoop(parameter, chamberIDList); }
        }
        /*-----------------------------------------------------
         * 1.打开气泵，测量第i路箱体
         * 2.等待30s（记录数据）
         * 3.计算数据
         * 4.是否最后一路箱体（否，回到1）（是SBA5调零，其他工作，i=1，回到1）
         * 
         * 
         * 
         *----------------------------------------------------- 
         */
        public void SBA5_Measure(object parameter, int[] ChamberID_List)
        {
            string value = (string)parameter;
            if (value.Equals("3"))
            {
                AnalyzerModel = "SBA5";
            }
            int t1 = 0; 
            int loopHander = First_Srart_Zero;//启动先调零
            casein = 0;
            caseIndex = 1;
            currentLoop = 1;
            int Dry_Time =0;
            bool _isFirstStartZeroCompleted = false; // 标记 First_Start_Zero 是否完成
        OneMeasurementData omd = new OneMeasurementData(caseNumber);
            List<OneChamber> chamberList = omd.get_measurement_list();
            while (true)
            {
                if (Form1.isStoppedByUser)
                {
                    Master_Command("KY", 0);
                    if (!WaitForCondition(() => stc_mcu14 != BakeData, 5000, () => Master_Command("KY", 0)))
                    {
                    }
                    Master_Command("KL", 0);//关闭干燥气泵
                    if (!WaitForCondition(() => stc_mcu14 != BakeData, 5000, () => Master_Command("KL", 0)))
                    {
                    }
                    Master_Command("KA", 1);
                    if (!WaitForCondition(() => stc_mcu14 != BakeData, 5000, () => Master_Command("KA", 1)))
                    {
                    }
                    slave_runflag = false;
                    master_runflag = false;
                    Form1.isStoppedByUser = false;
                    return;
                }
                else
                {
                    if (LoopSate)
                    {
                        switch (loopHander)
                        {
                            case First_Srart_Zero:

                                Form1.state = "调零";
                                if (!SBA5zeroTriggered) //调零是否已经触发
                                {
                                    Send_Command("KD", ChamberID_List[casein]); // SBA5关箱,开气路是一起的
                                    if (!WaitForCondition(() => stc_mcu14 != BakeData, 5000, () => Send_Command("KD", ChamberID_List[casein])))
                                    {
                                    }
                                    Master_Command("KB", 1); // 打开气泵
                                    if (!WaitForCondition(() => stc_mcu14 != BakeData, 5000, () => Master_Command("KD", 1)))
                                    {
                                    }
                                    Master_Command("KA", 0);//调零出气打开
                                    if (!WaitForCondition(() => stc_mcu14 != BakeData, 5000, () => Master_Command("KA", 0)))
                                    {
                                    }
                                    SBA5zeroTriggered = true;
                                }
                                ZeroingTime++;
                                if (SBA5zeroTriggered == true && ZeroingTime < 45)
                                {
                                    if (ZeroingTime == 10)
                                    {
                                        Master_Command("KA", 1);
                                        if (!WaitForCondition(() => stc_mcu14 != BakeData, 5000, () => Master_Command("KA", 1)))
                                        {
                                        }
                                    }
                                }
                                else
                                {
                                    SBA5zeroTriggered = false;
                                    ZeroingTime = 0;
                                    t1 = 0;
                                    loopHander = Start;
                                    goto case Start;                                 
                                }
                                break;
                            case Start:
                                _startTime = DateTime.Now;
                                loopHander = CLOSE_ONE_CASE;
                                goto case CLOSE_ONE_CASE;
                            case CLOSE_ONE_CASE:  // CLOSE_ONE_CASE
                                Form1.state = "Measuring";
                                WriteTail(creatFile(ChamberID_List[casein]), value); // 每个箱子第一次测量写表头
                                if(_isFirstStartZeroCompleted)
                                {
                                    Console.WriteLine("测量第2:" + ChamberID_List[casein]);
                                    if (casein == 0)
                                    {
                                        Send_Command("KD", ChamberID_List[casein]); // SBA5关箱,开气路是一起的
                                        if (!WaitForCondition(() => stc_mcu14 != BakeData, 5000, () => Send_Command("KD", ChamberID_List[casein])))
                                        {
                                        }
                                    }
                                    else
                                    {     //打开上一个箱体，通该箱体气路
                                        Send_Command("KC", ChamberID_List[casein - 1]); // 打开上一个箱体
                                        if (!WaitForCondition(() => stc_mcu14 != BakeData, 5000, () => Send_Command("KC", ChamberID_List[casein - 1])))
                                        {
                                        }
                                        Send_Command("KD", ChamberID_List[casein]);
                                        if (!WaitForCondition(() => stc_mcu14 != BakeData, 5000, () => Send_Command("KD", ChamberID_List[casein])))
                                        {
                                        }
                                    }
                                }
                                else
                                {
                                    Console.WriteLine("测量第1:" + ChamberID_List[casein]);
                                    _isFirstStartZeroCompleted = true;
                                }
                                loopHander = SAVE_DATA;
                                goto case SAVE_DATA;
                            case SAVE_DATA:
                                saveData(creatFile(ChamberID_List[casein]), AnalyzerModel); // 保存数据到txt文件                                                  //大循环做拟合
                                CAPTS_Suite.DataLine cycle_dl = new CAPTS_Suite.DataLine();
                                cycle_dl.time_string = DateTime.Now.ToString("HH:mm:ss");
                                int seconds = convertTime2sec(DateTime.Now.ToString("HH:mm:ss"));
                                cycle_dl.seconds = seconds;
                                cycle_dl.currentLoop = currentLoop;
                                //原机分析
                                    cycle_dl.co2 = Double.Parse(ChipPackages.C_CO2);
                                    cycle_dl.h2o = Double.Parse(ChipPackages.C_H2O);
                                
                                if (checkBox1_flag) //用户自定义温度、压强
                                {
                                    cycle_dl.temperature = Set_temperature;
                                    cycle_dl.air_pressure = Set_air_pressure;
                                }
                                else
                                {
                                    cycle_dl.temperature = Double.Parse(ChipPackages.C_T);
                                    cycle_dl.air_pressure = Double.Parse(ChipPackages.C_PA);

                                }
                                cycle_dl.ppfd = Double.Parse(ChipPackages.C_PPFD);
                                cycle_dl.relative_humidity = Double.Parse(ChipPackages.C_HR);

                                chamberList[casein].add_rawData(cycle_dl);
                                break;
                            case SD_STATUS_WAIT_FOR_SBA5ZERO:
                                Form1.state = "调零";
                                if (!SBA5zeroTriggered) //调零是否已经触发
                                {
                                    Master_Command("KA", 0);//调零出气打开
                                    if (!WaitForCondition(() => stc_mcu14 != BakeData, 5000, () => Master_Command("KA", 0)))
                                    {
                                    }
                                    SBA5zeroTriggered = true;
                                }
                                ZeroingTime++;
                                if (SBA5zeroTriggered == true && ZeroingTime < 45)
                                {
                                    if (ZeroingTime == 10)
                                    {
                                        Master_Command("KA", 1);
                                        if (!WaitForCondition(() => stc_mcu14 != BakeData, 5000, () => Master_Command("KA", 1)))
                                        {
                                        }
                                    }
                                }
                                else
                                {
                                    Send_Command("KC", ChamberID_List[caseNumber - 1]);
                                    if (!WaitForCondition(() => stc_mcu14 != BakeData, 5000, () => Send_Command("KC", ChamberID_List[caseNumber - 1])))
                                    {
                                    }
                                    SBA5zeroTriggered = false;
                                    ZeroingTime = 0;
                                    if (currentLoop == LoopCount)
                                    {
                                        currentLoop = 1;
                                        loopHander = Dry_CH;
                                        goto case Dry_CH;
                                    }
                                    else
                                    {
                                        t1 = 0;
                                        loopHander = Start;
                                        goto case Start;
                                    }
                                }
                                break;
                            case Dry_CH:
                                Form1.state = "干燥";
                                Dry_Time++;
                                if (Dry_Time==1)
                                {
                                    Master_Command("KB", 0);//关闭气泵
                                    if (!WaitForCondition(() => stc_mcu14 != BakeData, 5000, () => Master_Command("KB", 0)))
                                    {
                                    }
                                    Master_Command("KL", 1);//打开干燥气泵
                                    if (!WaitForCondition(() => stc_mcu14 != BakeData, 5000, () => Master_Command("KL", 1)))
                                    {
                                    }
                                }
                                else if(Dry_Time==600)//10*60干燥完成
                                {
                                    Master_Command("KL", 0);//关闭干燥气泵
                                    if (!WaitForCondition(() => stc_mcu14 != BakeData, 5000, () => Master_Command("KL", 0)))
                                    {
                                    }
                                    Master_Command("KB", 1);//关闭气泵
                                    if (!WaitForCondition(() => stc_mcu14 != BakeData, 5000, () => Master_Command("KB", 1)))
                                    {
                                    }
                                    t1 = 0;
                                    Dry_Time = 0;
                                    loopHander = Start;
                                    goto case Start;
                                }
                                break;
                            default:
                                //这个时候仪器处于，不记录数据，等待下一次抽气或者等待下一次循环
                                break;

                        }
                        t1++;
                        if (t1 == T1)
                        {
                            if (loopHander == SAVE_DATA)
                            {
                                chamberList[casein].caseindex = ChamberID_List[casein];
                                string Index = "1";
                                chamberList[casein].updateForSBA5(); // 调用每个箱子的updateFor4Loops方法，计算平均值和标准差
                                Index = chamberList[casein].caseindex.ToString();

                                int year = chamberList[casein].start_time.Year;
                                int month = chamberList[casein].start_time.Month;
                                int day = chamberList[casein].start_time.Day;
                                int doy = chamberList[casein].start_time.DayOfYear;
                                int sod = (int)chamberList[casein].start_time.TimeOfDay.TotalSeconds;
                                string currentTime = chamberList[casein].start_time.ToString("HH:mm:ss");
                                string current_endTime = chamberList[casein].end_time.ToString("HH:mm:ss");


                                //string CO2slope = chamberList[casein].slope_co2.ToString();
                                //string H2Oslope = chamberList[casein].slope_h2o.ToString();
                                //string CH4slope = chamberList[casein].slope_ch4.ToString();
                                //string N2Oslope = chamberList[casein].slope_n2o.ToString();
                                //string NH3_slope = chamberList[casein].slope_nh3.ToString();

                                ////添加 CO2slope
                                //AddValueToInnerDictionary(Form1.Fit_Data[Index], "CO2slope", CO2slope);

                                //// 添加 H2Oslope
                                //AddValueToInnerDictionary(Form1.Fit_Data[Index], "H2Oslope", H2Oslope);

                                //// 添加 CH4slope
                                //AddValueToInnerDictionary(Form1.Fit_Data[Index], "CH4slope", CH4slope);

                                //// 添加 N2Oslope
                                //AddValueToInnerDictionary(Form1.Fit_Data[Index], "N2Oslope", N2Oslope);

                                //// 添加 NH3_slope
                                //AddValueToInnerDictionary(Form1.Fit_Data[Index], "NH3_slope", NH3_slope);


                                double AC = Math.Round(chamberList[casein].Ac_Li, 2);
                                double EC = Math.Round(chamberList[casein].Ec_Li, 2);
                                double MER = Math.Round(chamberList[casein].MER_Li, 2);
                                double N2OER = Math.Round(chamberList[casein].N2OER_Li, 2);
                                double NH3ER = Math.Round(chamberList[casein].NH3ER_PI, 2);
                                double ACR2 = Math.Round(chamberList[casein].AcR2, 2);
                                double ECR2 = Math.Round(chamberList[casein].EcR2, 2);
                                double MERR2 = Math.Round(chamberList[casein].MerR2, 2);
                                double N2OR2 = Math.Round(chamberList[casein].N2oR2, 2);
                                double ppfd_cov = Math.Round(chamberList[casein].CvPPFD, 2);
                                //获取该箱体中的平均数据
                                CAPTS_Suite.DataLine avgdata = chamberList[casein].get_avgData();
                                double temperature = avgdata.temperature;
                                double relative_humidity = avgdata.relative_humidity;
                                double ppfd = avgdata.ppfd;
                                double air_pressure = avgdata.air_pressure;
                                double CO2 = avgdata.co2;
                                double h2o = avgdata.h2o;
                                double ch4 = avgdata.ch4;
                                double n2o = avgdata.n2o;
                                double nh3 = avgdata.nh3;

                                double CO2_std = avgdata.co2_StdDev;
                                double h2o_std = avgdata.h2o_StdDev;
                                double ch4_std = avgdata.ch4_StdDev;
                                double n2o_std = avgdata.h2o_StdDev;
                                double nh3_std = avgdata.nh3_StdDev;

                                string Epath_2 = @"E:\CAPTS_data\";
                                string fitingfile = "";
                                //保存数,CAPTS101不输出下面文件
                                if (Directory.Exists(Epath_2))
                                {
                                    fitingfile = @"E:\\CAPTS_data\" + _startTime.ToString("yyyyMMdd") + "cycle_fiting.csv";
                                }
                                else
                                {
                                    fitingfile = @"D:\\CAPTS_data\" + _startTime.ToString("yyyyMMdd") + "cycle_fiting.csv";
                                }
                                string str2 = year.ToString() + "," + month.ToString() + "," + day.ToString() + "," + doy.ToString() + "," + sod.ToString() + "," + currentTime + "," + current_endTime + "," + "Chamber" + Index + "," + temperature.ToString() + "," + relative_humidity.ToString() + "," + ppfd.ToString() + "," + air_pressure.ToString() + "," + CO2.ToString() + "," + CO2_std.ToString() + "," + chamberList[casein].slope_co2.ToString() + "," + chamberList[casein].Ac_Li.ToString() + "," + ACR2.ToString() + "," + h2o.ToString() + "," + h2o_std.ToString() + "," + chamberList[casein].slope_h2o.ToString() + "," + chamberList[casein].Ec_Li.ToString() + "," + ECR2.ToString() + "," + ch4.ToString() + "," + ch4_std.ToString() + "," + chamberList[casein].slope_ch4.ToString() + "," + chamberList[casein].MER_Li.ToString() + "," + MERR2.ToString() + "," + n2o.ToString() + "," + n2o_std.ToString() + "," + chamberList[casein].slope_n2o.ToString()
                                    + "," + chamberList[casein].N2OER_Li.ToString() + "," + N2OR2.ToString() + "," + nh3.ToString() + "," + nh3_std.ToString() + "," + chamberList[casein].slope_nh3.ToString() + "," + chamberList[casein].NH3ER_PI.ToString() + "," + ppfd_cov.ToString();
                                if (!File.Exists(fitingfile))
                                {
                                    using (StreamWriter writer = File.CreateText(fitingfile))
                                    {
                                        writer.WriteLine("Year" + "," + "Month" + "," + "Day" + "," + "Doy" + "," + "Seconds" + "," + "Start_Time" + "," + "End_Time" + "," + "ChamberID" + "," + "temperature(oC)" + "," + "relative humidity(%)"
                + "," + "PPFD(umol.m-2.s-1)" + "," + "air pressure(kPa)" + "," + "CO2_Mean(ppm)" + "," + "CO2_StdDev" + "," + "CO2 Slope" + "," + " Ac(umol.m-2 ground area.s-1)" + "," + "R2(AC)" + "," + "H2O_Mean(ppm)" + "," + "H2O_StdDev" + "," + "H2O Slope" + "," + "EC(umol.m-2 ground area.s-1)" + "," + "R2(EC)" + "," + "CH4_Mean(ppb)" + "," + "CH4_StdDev" + "," + "CH4 Slope" + "," + " MER(umol.m-2 ground area.s-1)" + "," + "R2(MER)" + "," + "N2O_Mean(ppb)" + "," + "N2O_StdDev" + "," + "N2O Slope" + "," + "N2OER(umol.m-2 ground area.s-1)" + "," + "R2(N2OER)" + "," + "NH3_Mean" + "," + "NH3_StdDev" + "," + "NH3 Slope" + "," + " NH3ER(umol.m-2 ground area.s-1)" + "," + "PPFD coefficient of variation (%)");
                                        writer.WriteLine(str2);
                                    }
                                    //Console.WriteLine("循环数据拟合第"+ key1+"测量箱数据已成功写入文件！");
                                }
                                else
                                {
                                    using (StreamWriter writer = new StreamWriter(fitingfile, true))
                                    {
                                        writer.WriteLine(str2);
                                    }
                                }
                                Form1.slope_time = Convert.ToDateTime(chamberList[casein].get_goodDataList()[0].time_string);
                                omd.get_measurement_list().Clear(); //释放资源，接收下次数据
                                omd = new OneMeasurementData(caseNumber);
                                chamberList = omd.get_measurement_list();
                                if (caseIndex < caseNumber)//没到最后一个箱体
                                {
                                    caseIndex++;
                                    casein++;
                                    loopHander = Start;
                                }
                                else//最后一个
                                {
                                    Send_Command("KC", ChamberID_List[casein]);
                                    if (!WaitForCondition(() => stc_mcu14 != BakeData, 5000, () => Send_Command("KC", ChamberID_List[casein])))
                                    {
                                    }
                                    caseIndex = 1;
                                    casein = 0;
                                    currentLoop++;
                                    Send_Command("KD", ChamberID_List[caseNumber-1]);
                                    if (!WaitForCondition(() => stc_mcu14 != BakeData, 5000, () => Send_Command("KD", ChamberID_List[caseNumber-1])))
                                    {
                                    }
                                    loopHander = SD_STATUS_WAIT_FOR_SBA5ZERO;
                                }
                            }
                            t1 = 0;
                        }
                    }
                }
                Thread.Sleep(1000);
            }
        }
        // measureLoop核心函数

        public async void measureLoop(object parameter, int[] ChamberID_List)
        {
            string value = (string)parameter;
            if (value.Equals("1"))
            {
                AnalyzerModel = "LICOR";
            }
            else 
            {
                AnalyzerModel = "PICARRO";
            }

            Pro_State = "measureLoop Run !!!";
            string NoDry = "KJ:" + MasterToSlave.ToString();//不干燥的气路
            string NoDry_1 = "KJ:" + (MasterToSlave+1).ToString();//干燥的气路
            int t1 = 0, t2 = 0, t3 = 0; // 超时时间设置为 5 秒; 
            int loopHander = Start;//switch句柄
            casein = 0;
            caseIndex = 1;
            currentLoop = 1;
            int Dry_time = 0;
            OneMeasurementData omd = new OneMeasurementData(caseNumber);
            List<OneChamber> chamberList = omd.get_measurement_list();
            while (true)
            {
                if (Form1.isStoppedByUser)
                {
                    Master_Command("KY", 0);
                    if (!WaitForCondition(() => stc_mcu14 != BakeData, 5000, () => Master_Command("KY", 0)))
                    {
                    }
                    if (slave_connect)
                    {
                        Slave_Command("KY", 0);
                        if (!WaitForCondition(() => stc_mcu14_slave != BakeData, 5000, () => Slave_Command("KY", 0)))
                        {
                        }

                    }
                    slave_runflag = false;
                    master_runflag = false;
                    Form1.isStoppedByUser = false;
                    return;
                }
                else
                {
                    if (LoopSate)
                    {
                        switch (loopHander)
                        {
                            case Start:
                                _startTime = DateTime.Now;
                                loopHander = CLOSE_ONE_CASE;
                                goto case CLOSE_ONE_CASE;
                            case CLOSE_ONE_CASE:  // CLOSE_ONE_CASE
                                Form1.state = "Measuring";
                                if (currentLoop == 1)
                                {
                                    WriteTail(creatFile(ChamberID_List[casein]), value); // 第一次测量写表头
                                }
                                if (casein != 0)
                                {
                                    if (ChamberID_List[casein] <= Master_Port && ChamberID_List[casein - 1] > Master_Port)//上一次测量从机，本次测量主机，需关闭从机气泵
                                    {
                                        Send_Command("KM", ChamberID_List[casein - 1]); // 关闭从机气路
                                        if (!WaitForCondition(() => stc_mcu14_slave != BakeData, 5000, () => Send_Command("KM", ChamberID_List[casein - 1])))
                                        {
                                        }
                                        Set_Pump("KB", 0, Address2);// 发指令，关从机气泵
                                        if (!WaitForCondition(() => stc_mcu14_slave != BakeData, 5000, () => Set_Pump("KB", 0, Address2)))
                                        {
                                        }
                                        slave_runflag = false;
                                        //关闭从机气泵
                                    }
                                }

                                //if (ChamberID_List[casein - 1] <= Master_Port && ChamberID_List[casein] > Master_Port)
                                //{ 
                                    
                                //}
                                if (!master_runflag && ChamberID_List[casein] <= Master_Port) // 主机未启动且属于主机端口
                                {
                                    master_runflag = true; // 主机已启动
                                    Send_Command("KF", ChamberID_List[casein]); // 关箱开气路，启动气泵，闭合123电磁阀
                                    if (!WaitForCondition(() => stc_mcu14!= BakeData, 5000, () => Send_Command("KF", ChamberID_List[casein])))
                                    {
                                    }
                                }
                                else if (!slave_runflag && ChamberID_List[casein] > Master_Port) // 从机未启动且属于从机端口，开从机也得开主机气泵，和闭合主机123号电磁阀
                                {
                                    if (!master_runflag)
                                    {
                                        master_runflag = true; // 主机已启动
                                        Set_Pump("KH", 0, Address1);// 发指令，闭合主机123号电磁阀
                                        if (!WaitForCondition(() => stc_mcu14!= BakeData, 5000, () => Set_Pump("KH", 0, Address1)))
                                        {
                                        }
                                        Set_Pump("KB", 1, Address1);// 发指令，开主机气泵
                                        if (!WaitForCondition(() => stc_mcu14!= BakeData, 5000, () => Set_Pump("KB", 1, Address1)))
                                        {
                                        }
                                    }
                                    Send_Command("KV", MasterToSlave); // 打开主从机气路，MasterToSlave为连接端口
                                    if (!WaitForCondition(() => stc_mcu14!= BakeData, 5000, () => Send_Command("KV", MasterToSlave)))
                                    {
                                    }
                                    slave_runflag = true; // 从机已启动
                                    Send_Command("KF", ChamberID_List[casein]); // 关箱开气路，启动气泵，闭合123电磁阀
                                    if (!WaitForCondition(() => stc_mcu14_slave != BakeData, 5000, () => Send_Command("KF", ChamberID_List[casein])))
                                    {
                                    }
                                }
                                else // 主机和从机均已启动
                                {
                                    Send_Command("KX", ChamberID_List[casein]); // 关箱开气路
                                    if(ChamberID_List[casein] <= Master_Port)//主机的判断
                                    {
                                        if (!WaitForCondition(() => stc_mcu14 != BakeData, 5000, () => Send_Command("KX", ChamberID_List[casein])))
                                        {
                                        }
                                    }
                                    else
                                    {
                                        if (!WaitForCondition(() => stc_mcu14_slave != BakeData, 5000, () => Send_Command("KX", ChamberID_List[casein])))
                                        {
                                        }
                                    }
                                }

                                loopHander = SD_STATUS_STORE_TAIL;
                                goto case SD_STATUS_STORE_TAIL;
                            case OPEN_LAST_CLOSE_NEXT: //打开上一个箱体，通当前气路
                                if (casein == 0)//第一个，无箱盖打开，只通气路
                                {
                                    if (!master_runflag && ChamberID_List[casein] <= Master_Port)//主机未启动
                                    {
                                        master_runflag = true;
                                        Set_Pump("KB", 1, Address1);// 发指令，开主机气泵
                                        if (!WaitForCondition(() => stc_mcu14!= BakeData, 5000, () => Set_Pump("KB", 1, Address1)))
                                        {
                                        }
                                    }
                                    else if (!slave_runflag && ChamberID_List[casein] >Master_Port)//从机未启动
                                    {
                                        if (!master_runflag)
                                        {
                                            master_runflag = true; // 主机已启动
                                            Set_Pump("KB", 1, Address1);// 发指令，开主机气泵
                                            if (!WaitForCondition(() => stc_mcu14!= BakeData, 5000, () => Set_Pump("KB", 1, Address1)))
                                            {
                                            }
                                        }
                                        Send_Command("KV", MasterToSlave); // 打开主从机气路，MasterToSlave为连接端口
                                        if (!WaitForCondition(() => stc_mcu14!= BakeData, 5000, () => Send_Command("KV", MasterToSlave))){MessageBox.Show("打开主机气路响应超时，请检查主机连接");}
                                        slave_runflag = true;
                                        Set_Pump("KB", 1, Address2);// 发指令，开从机气泵
                                        if (!WaitForCondition(() => stc_mcu14_slave != BakeData, 1000, () => Set_Pump("KB", 1, Address2)))
                                        {
                                        }
                                    }
                                    Send_Command("KV", ChamberID_List[casein]);//开气路,

                                    if (ChamberID_List[casein] <= Master_Port)//主机的判断
                                    {
                                        if (!WaitForCondition(() => stc_mcu14 != BakeData, 5000, () => Send_Command("KV", ChamberID_List[casein])))
                                        {
                                        }
                                    }
                                    else
                                    {
                                        if (!WaitForCondition(() => stc_mcu14_slave != BakeData, 5000, () => Send_Command("KV", ChamberID_List[casein])))
                                        {
                                        }
                                    }

                                }
                                else
                                {
                                    if (ChamberID_List[casein] <= Master_Port && ChamberID_List[casein - 1] > Master_Port)//上一次测量从机，本次测量主机
                                    {
                                        Send_Command("KM", ChamberID_List[casein - 1]); // 关闭从机气路
                                        if (!WaitForCondition(() => stc_mcu14_slave != BakeData, 5000, () => Send_Command("KM", ChamberID_List[casein - 1])))
                                        {
                                        }
                                        Set_Pump("KB", 0, Address2);// 发指令，关从机气泵
                                        if (!WaitForCondition(() => stc_mcu14_slave != BakeData, 5000, () => Set_Pump("KB", 0, Address2)))
                                        {
                                        }
                                        slave_runflag = false;
                                        //关闭从机气泵
                                    }
                                    if (!master_runflag && ChamberID_List[casein] <= Master_Port)//主机未启动
                                    {
                                        master_runflag = true;
                                        Set_Pump("KB", 1, Address1);// 发指令，开主机气泵
                                        if (!WaitForCondition(() => stc_mcu14!= BakeData, 5000, () => Set_Pump("KB", 1, Address1)))
                                        {
                                        }
                                    }
                                    if (!slave_runflag && ChamberID_List[casein] > Master_Port)//从机未启动
                                    {
                                        if (!master_runflag)
                                        {
                                            master_runflag = true; // 主机已启动
                                            Set_Pump("KB", 1, Address1);// 发指令，开主机气泵
                                            if (!WaitForCondition(() => stc_mcu14!= BakeData, 5000, () => Set_Pump("KB", 1, Address1)))
                                            {
                                            }
                                        }
                                        Send_Command("KV", MasterToSlave); // 打开主从机气路，MasterToSlave为连接端口
                                        if (!WaitForCondition(() => stc_mcu14!= BakeData, 5000, () => Send_Command("KV", MasterToSlave))) { MessageBox.Show("打开主从机连接气路响应超时，请检查主机连接"); }
                                        slave_runflag = true;
                                        Set_Pump("KB", 1, Address2);// 发指令，开从机气泵
                                        if (!WaitForCondition(() => stc_mcu14_slave != BakeData, 1000, () => Set_Pump("KB", 1, Address2))){}
                                    }
                                    Send_Command("KC", ChamberID_List[casein - 1]);//开上一路箱体

                                    if (ChamberID_List[casein-1] <= Master_Port)//主机的判断
                                    {
                                        if (!WaitForCondition(() => stc_mcu14 != BakeData, 1000, () => Send_Command("KC", ChamberID_List[casein - 1]))) { MessageBox.Show("打开主机箱门响应超时，请检查主机连接"+ ChamberID_List[casein - 1]); }
                                    }
                                    else
                                    {
                                        if (!WaitForCondition(() => stc_mcu14_slave != BakeData, 1000, () => Send_Command("KC", ChamberID_List[casein - 1]))) { MessageBox.Show("打开从机箱门响应超时，请检查主机连接" + ChamberID_List[casein - 1]); }
                                    }


                                    Send_Command("KV", ChamberID_List[casein]);//通当前气路

                                    if (ChamberID_List[casein] <= Master_Port)//主机的判断
                                    {
                                        if (!WaitForCondition(() => stc_mcu14 != BakeData, 5000, () => Send_Command("KV", ChamberID_List[casein]))) { MessageBox.Show("打开主机气路响应超时，请检查主机连接"); }
                                    }
                                    else
                                    {
                                        if (!WaitForCondition(() => stc_mcu14_slave != BakeData, 5000, () => Send_Command("KV", ChamberID_List[casein]))) { MessageBox.Show("打开从机气路响应超时，请检查主机连接"); }
                                    }

                                }

                                goto case SD_STATUS_STORE_TAIL;
                            case OPEN_EXTRA_TUBE: // OPEN_EXTRA_TUBE , 打开“防堵气路”，关闭所有测量箱子的全部气路。
                                Form1.state = "Waiting";
                                Master_Command("KB", 0);// 发指令，关主机气泵
                                if (!WaitForCondition(() => stc_mcu14 != BakeData, 1000, () => Master_Command("KB", 0)))
                                {
                                }
                                master_runflag = false;//主机气泵关闭，代表已经停止
                                if (slave_connect)//如果从机启动了才关
                                {
                                    Send_Command("KM", MasterToSlave);//将主机与从机连接的气路关闭，1为主机
                                    if (!WaitForCondition(() => stc_mcu14!= BakeData, 5000, () => Send_Command("KM", MasterToSlave)))
                                    {
                                    }
                                    Set_Pump("KB", 0, Address2);// 发指令，关从机气泵
                                    if (!WaitForCondition(() => stc_mcu14_slave != BakeData, 1000, () => Set_Pump("KB", 0, Address2)))
                                    {
                                    }
                                    slave_runflag = false;
                                }

                                loopHander = 0;
                                break;
                            case Only_One://若只设置一次循环 打开上一个箱体，关闭下一个箱体，同下一路气路
                                if (caseIndex == 1)//不需要打开上一个箱体
                                {
                                    if (!master_runflag && ChamberID_List[casein] <= Master_Port)//主机未启动
                                    {
                                        master_runflag = true;
                                        Set_Pump("KB", 1, Address1);// 发指令，开主机气泵
                                        if (!WaitForCondition(() => stc_mcu14!= BakeData, 5000, () => Set_Pump("KB", 1, Address1)))
                                        {
                                        }
                                    }
                                    if (!slave_runflag && ChamberID_List[casein] > Master_Port)//从机未启动
                                    {
                                        if (!master_runflag)
                                        {
                                            master_runflag = true; // 主机已启动
                                            Set_Pump("KB", 1, Address1);// 发指令，开主机气泵
                                            if (!WaitForCondition(() => stc_mcu14!= BakeData, 5000, () => Set_Pump("KB", 1, Address1)))
                                            {
                                            }
                                        }
                                        Send_Command("KV", MasterToSlave); // 打开主从机气路，MasterToSlave为连接端口
                                        if (!WaitForCondition(() => stc_mcu14!= BakeData, 5000, () => Send_Command("KV", MasterToSlave))) { MessageBox.Show("打开主机气路响应超时，请检查主机连接"); }
                                        slave_runflag = true;
                                        Set_Pump("KB", 1, Address2);// 发指令，开从机气泵
                                        if (!WaitForCondition(() => stc_mcu14_slave != BakeData, 1000, () => Set_Pump("KB", 1, Address2)))
                                        {
                                        }
                                    }
                                    Send_Command("KX", ChamberID_List[casein]);//闭合从机1号箱，通从机1号气路

                                    if (ChamberID_List[casein] <= Master_Port)//主机的判断
                                    {
                                        if (!WaitForCondition(() => stc_mcu14 != BakeData, 1000, () => Send_Command("KX", ChamberID_List[casein]))) { }
                                    }
                                    else
                                    {
                                        if (!WaitForCondition(() => stc_mcu14_slave != BakeData, 1000, () => Send_Command("KX", ChamberID_List[casein]))) { }
                                    }

                                }
                                else
                                {
                                    if (ChamberID_List[casein] <= Master_Port && ChamberID_List[casein - 1] > Master_Port)//上一次测量是从机
                                    {
                                        Set_Pump("KB", 0, Address2);// 发指令，关从机气泵
                                        if (!WaitForCondition(() => stc_mcu14_slave != BakeData, 5000, () => Set_Pump("KB", 0, Address2)))
                                        {
                                        }

                                        Send_Command("KM", ChamberID_List[casein - 1]); // 关闭从机气路
                                        if (!WaitForCondition(() => stc_mcu14_slave != BakeData, 5000, () => Send_Command("KM", ChamberID_List[casein - 1])))
                                        {
                                        }
                                        slave_runflag = false;
                                        //关闭从机气泵
                                    }
                                    if (!master_runflag && ChamberID_List[casein] <= Master_Port)//主机未启动
                                    {
                                        master_runflag = true;
                                        Set_Pump("KB", 1, Address1);// 发指令，开主机气泵
                                        if (!WaitForCondition(() => stc_mcu14!= BakeData, 5000, () => Set_Pump("KB", 1, Address1)))
                                        {
                                        }
                                    }
                                    if (!slave_runflag && ChamberID_List[casein] > Master_Port)//主机未启动
                                    {
                                        if (!master_runflag)
                                        {
                                            master_runflag = true; // 主机已启动
                                            Set_Pump("KB", 1, Address1);// 发指令，开主机气泵
                                            if (!WaitForCondition(() => stc_mcu14!= BakeData, 5000, () => Set_Pump("KB", 1, Address1)))
                                            {
                                            }
                                        }
                                        Send_Command("KV", MasterToSlave); // 打开主从机气路，MasterToSlave为连接端口
                                        if (!WaitForCondition(() => stc_mcu14!= BakeData, 5000, () => Send_Command("KV", MasterToSlave))) { MessageBox.Show("打开主机气路响应超时，请检查主机连接"); }
                                        slave_runflag = true;

                                        Set_Pump("KB", 1, Address2);// 发指令，开从机气泵
                                        if (!WaitForCondition(() => stc_mcu14_slave != BakeData, 1000, () => Set_Pump("KB", 1, Address2))){ }
                                    }
                                    Send_Command("KC", ChamberID_List[casein - 1]);//打开上一个箱体

                                    if (ChamberID_List[casein - 1] <= Master_Port)//主机的判断
                                    {
                                        if (!WaitForCondition(() => stc_mcu14 != BakeData, 1000, () => Send_Command("KC", ChamberID_List[casein - 1])))
                                        {
                                        }
                                    }
                                    else
                                    {
                                        if (!WaitForCondition(() => stc_mcu14_slave != BakeData, 1000, () => Send_Command("KC", ChamberID_List[casein - 1])))
                                        {
                                        }
                                    }


                                    Send_Command("KX", ChamberID_List[casein]);//闭合从机1号箱，通从机1号气路

                                    if (ChamberID_List[casein] <= Master_Port)//主机的判断
                                    {
                                        if (!WaitForCondition(() => stc_mcu14 != BakeData, 1000, () => Send_Command("KX", ChamberID_List[casein])))
                                        {
                                        }
                                    }
                                    else
                                    {
                                        if (!WaitForCondition(() => stc_mcu14_slave != BakeData, 1000, () => Send_Command("KX", ChamberID_List[casein])))
                                        {
                                        }
                                    }


                                }
                                goto case SD_STATUS_STORE_TAIL;
                            case Dry_CH://干燥气路
                                Form1.state = "Drying->1";
                                Master_Command("KJ", 1);//干燥主机气路
                                if (!WaitForCondition(() => stc_mcu14!= BakeData, 1000, () => Master_Command("KJ", 1)))
                                {
                                }
                                if (slave_connect)
                                {
                                    Slave_Command("KJ", 1);//干燥从机气路
                                    if (!WaitForCondition(() => stc_mcu14_slave != BakeData, 1000, () => Slave_Command("KJ", 1)))
                                    {
                                    }
                                }
                                loopHander = Dry_MasterToSlave;
                                break;
                            case Dry_MasterToSlave://跳过的气路
                                if (NoDry == stc_mcu14)//停止主机气泵,此气路不干燥
                                {
                                    if (slave_connect)//从机连接再执行
                                    {
                                        Master_Command("KB", 0);// 发指令，关主机气泵
                                        if (!WaitForCondition(() => stc_mcu14 != BakeData, 5000, () => Master_Command("KB", 0)))
                                        {
                                        }
                                        if (MasterToSlave == 16)//此时关闭气泵不需要打开了
                                        {
                                            loopHander = Dry_One;//等待干燥完成
                                        }
                                        else//等待这一路时间过去，打开气泵继续完成后续干燥
                                        {
                                            loopHander = Wait;
                                        }

                                    }
                                    else//不连接则不执行
                                    {
                                        loopHander = 0;
                                    }
                                }
                                break;
                            case Wait:                            
                                if (NoDry_1 == stc_mcu14)//,到了下一个，打开主机气泵继续完成后续干燥
                                {
                                    Master_Command("KB", 1);// 发指令，开主机气泵
                                    if (!WaitForCondition(() => stc_mcu14 != BakeData, 5000, () => Master_Command("KB", 1)))
                                    {
                                    }
                                    loopHander = Wait_Dry;
                                }
                                else {}
                                break; 
                            case Wait_Dry:
                                if (stc_mcu14 == "KJ:16")//,等16等待主从机干燥完成，再干燥主机连接从机的管子，上一步已经开过气泵了，所以这里不需要再开
                                {
                                    if (slave_connect)//从机连接才执行下面
                                    {
                                        Form1.state = "Wait_16";
                                        loopHander = Dry_One;
                                        Dry_time = 0;
                                        goto case Dry_One;
                                    }
                                    else
                                    {
                                        loopHander = OPEN_EXTRA_TUBE;
                                    }
                                }
                                else//继续等待
                                {
                                    loopHander = Wait_Dry;
                                }


                                break;
                            case Dry_One:
                                Form1.state = "Drying->2";
                                Dry_time++;
                                if (Dry_time == 22)
                                {
                                    Send_Command("KV", MasterToSlave); // 打开主从机气路
                                    if (!WaitForCondition(() => stc_mcu14 != BakeData, 5000, () => Send_Command("KV", MasterToSlave)))
                                    {
                                    }
                                    Master_Command("KH", 0);//主机电磁阀闭合
                                    if (!WaitForCondition(() => stc_mcu14 != BakeData, 5000, () => Master_Command("KH", 0)))
                                    {
                                    }
                                    Set_Pump("KB", 1, Address1);// 发指令，开主机气泵
                                    if (!WaitForCondition(() => stc_mcu14 != BakeData, 5000, () => Set_Pump("KB", 1, Address1)))
                                    {
                                    }
                                    master_runflag = true;

                                    Slave_Command("KI", 1); // 从机电磁阀2打开，13闭合
                                    if (!WaitForCondition(() => stc_mcu14_slave != BakeData, 5000, () => Slave_Command("KI", 1)))
                                    {
                                    }
                                    Send_Command("KV", 17);
                                    if (!WaitForCondition(() => stc_mcu14_slave != BakeData, 5000, () => Send_Command("KV", 17)))
                                    {
                                    }
                                    Set_Pump("KB", 1, Address2);// 发指令，开从机气泵
                                    if (!WaitForCondition(() => stc_mcu14_slave != BakeData, 5000, () => Set_Pump("KB", 1, Address2)))
                                    {
                                    }
                                    slave_runflag = true;

                                }
                                else if (Dry_time == 62)
                                {
                                    Dry_time = 0;
                                    Set_Pump("KB", 0, Address1);// 发指令，关主机气泵
                                    if (!WaitForCondition(() => stc_mcu14 != BakeData, 5000, () => Set_Pump("KB", 0, Address1)))
                                    {
                                    }
                                    Send_Command("KM", MasterToSlave); // 打开主从机气路
                                    if (!WaitForCondition(() => stc_mcu14 != BakeData, 5000, () => Send_Command("KM", MasterToSlave)))
                                    {
                                        MessageBox.Show("打开主从机气路响应超时，请检查主机连接");
                                    }
                                    Set_Pump("KB", 0, Address2);// 发指令，关从机气泵
                                    if (!WaitForCondition(() => stc_mcu14_slave != BakeData, 5000, () => Set_Pump("KB", 0, Address2)))
                                    {
                                    }
                                    Send_Command("KM", 17);
                                    if (!WaitForCondition(() => stc_mcu14_slave != BakeData, 5000, () => Send_Command("KM", 17)))
                                    {
                                    }

                                    Slave_Command("KI", 0); // 从机电磁阀闭合
                                    if (!WaitForCondition(() => stc_mcu14_slave != BakeData, 5000, () => Slave_Command("KI", 0)))
                                    {
                                    }


                                    slave_runflag = false;
                                    master_runflag = false;
                                    loopHander = 0; // 切换到另一个状态
                                    break;
                                }
                                else
                                {
                                    break; // 这里确保在 `Dry_time` 未到达 20 时直接退出 case
                                }
                                break;
                            case SD_STATUS_STORE_TAIL:
                                writeflag(creatFile(ChamberID_List[casein]), ">" + "Data from iteration:" + currentLoop);
                                loopHander = SAVE_DATA;
                                goto case SAVE_DATA;
                            case SAVE_DATA:
                                saveData(creatFile(ChamberID_List[casein]), AnalyzerModel); // 保存数据到txt文件                                                  //大循环做拟合
                                CAPTS_Suite.DataLine cycle_dl = new CAPTS_Suite.DataLine();
                                cycle_dl.time_string = DateTime.Now.ToString("HH:mm:ss");
                                int seconds = convertTime2sec(DateTime.Now.ToString("HH:mm:ss"));
                                cycle_dl.seconds = seconds;
                                cycle_dl.currentLoop = currentLoop;
                                if (CAPTS_Borker.AnalyzerType)//判断是外接分析器还是原机分析器
                                {   //原机分析
                                    cycle_dl.co2 = Double.Parse(ChipPackages.C_CO2);
                                    cycle_dl.h2o = Double.Parse(ChipPackages.C_H2O);
                                }
                                else
                                {
                                    try
                                    {
                                        if (Form1.Device_Flag.Equals("1"))
                                        {
                                            cycle_dl.co2 = Double.Parse(LI_CO2);
                                            cycle_dl.h2o = Double.Parse(LI_H2O);
                                            cycle_dl.ch4 = Double.Parse(LI_CH4);
                                            cycle_dl.n2o = Double.Parse(LI_N2O);
                                        }
                                        else if (Form1.Device_Flag.Equals("2"))
                                        {
                                            cycle_dl.co2 = Double.Parse(CAPTS_Picarro.PI_CO2_dry);
                                            cycle_dl.h2o = Double.Parse(CAPTS_Picarro.PI_H2O);
                                            cycle_dl.ch4 = Double.Parse(CAPTS_Picarro.PI_CH4_dry);
                                            cycle_dl.n2o = Double.Parse(CAPTS_Picarro.PI_N2O_dry);
                                            cycle_dl.nh3 = Double.Parse(CAPTS_Picarro.PI_NH3);
                                        }
                                    }
                                    catch
                                    {
                                    }
                                }
                                if (checkBox1_flag) //用户自定义温度、压强
                                {
                                    cycle_dl.temperature = Set_temperature;
                                    cycle_dl.air_pressure = Set_air_pressure;
                                }
                                else
                                {
                                    cycle_dl.temperature = Double.Parse(ChipPackages.C_T);
                                    cycle_dl.air_pressure = Double.Parse(ChipPackages.C_PA);

                                }
                                cycle_dl.ppfd = Double.Parse(ChipPackages.C_PPFD);
                                cycle_dl.relative_humidity = Double.Parse(ChipPackages.C_HR);

                                chamberList[caseIndex - 1].add_rawData(cycle_dl);
                                break;
                            default:
                                //这个时候仪器处于，不记录数据，等待下一次抽气或者等待下一次循环
                                break;
                        }
                        // 以下部分是while循环中的，用循环次数计时，循环每次停1s
                        t1++; t2++; t3++;
                        if (t1 == T1)
                        {
                            chamberList[caseIndex - 1].caseindex = ChamberID_List[casein];
                            if (currentLoop == LoopCount && LoopCount == 1)
                            {
                                if (caseIndex < caseNumber)
                                {
                                    caseIndex++; // 下一个箱子
                                    casein++;//数组下标++
                                    t1 = 0;
                                    loopHander = Only_One;
                                }
                                else
                                {
                                    Send_Command("KY", ChamberID_List[casein]);//开最后一个箱子，关闭最后一个气路
                                    if(ChamberID_List[casein]<=Master_Port)
                                    {
                                        if (!WaitForCondition(() => stc_mcu14 != BakeData, 5000, () => Send_Command("KY", ChamberID_List[casein])))
                                        {
                                        }
                                    }
                                    else
                                    {
                                        if (!WaitForCondition(() => stc_mcu14_slave != BakeData, 5000, () => Send_Command("KY", ChamberID_List[casein])))
                                        {
                                        }
                                    }
                                        loopHander = OPEN_EXTRA_TUBE;//这里会关闭主从机气泵
                                }

                            }
                            else
                            {
                                if (caseIndex < caseNumber)
                                {
                                    caseIndex++; // 下一个箱子
                                    casein++;//数组下标++
                                    if (currentLoop < LoopCount)
                                    {
                                        t1 = 0;
                                        // 立即开始下一个箱子的闭合和抽气
                                        loopHander = CLOSE_ONE_CASE;
                                    }
                                    else // j==M
                                    {
                                        t1 = 0;
                                        loopHander = OPEN_LAST_CLOSE_NEXT;
                                    }

                                }
                                else//caseIndex==caseNumber，最后一个箱子
                                {

                                    if (currentLoop == LoopCount)
                                    {
                                        Send_Command("KY", ChamberID_List[casein]);//最后一轮为开i-1，通i，所以这里测量结束需要打开最后一个箱子并关闭气路

                                        if (ChamberID_List[casein] <= Master_Port)
                                        {
                                            if (!WaitForCondition(() => stc_mcu14 != BakeData, 5000, () => Send_Command("KY", ChamberID_List[casein]))) { }
                                        }
                                        else
                                        {
                                            if (!WaitForCondition(() => stc_mcu14_slave != BakeData, 5000, () => Send_Command("KY", ChamberID_List[casein]))) { }
                                        }


                                        loopHander = OPEN_EXTRA_TUBE;//这里会关闭主从机气路
                                    }
                                    else// 停止抽气，停止测量气体浓度，防止堵气需要开通“防堵气路”
                                    {//该轮循环结束，但不是最后一轮循环
                                        Send_Command("KM", ChamberID_List[casein]); // 关闭最后一路气路

                                        if (ChamberID_List[casein] <= Master_Port)
                                        {
                                            if (!WaitForCondition(() => stc_mcu14 != BakeData, 5000, () => Send_Command("KM", ChamberID_List[casein]))) { }
                                        }
                                        else
                                        {
                                            if (!WaitForCondition(() => stc_mcu14_slave != BakeData, 5000, () => Send_Command("KM", ChamberID_List[casein]))) { }
                                        }


                                        loopHander = OPEN_EXTRA_TUBE;//关闭主从机气泵
                                    }

                                }
                            }

                        }
                        if (t2 == T2)
                        {
                            // 等待抽气间隔时间到了，开始下一次的抽气，从第1号箱开始

                            if (currentLoop < LoopCount)
                            {
                                casein = 0; caseIndex = 1; currentLoop++;
                                t1 = 0; t2 = 0;
                                loopHander = CLOSE_ONE_CASE;
                                // 当前最后一个箱子抽气结束，等待进入第j次抽气，第j次抽气从第1号箱子开始
                            }
                            else // j==M // 这时候是完成了4次loop结束
                            {
                                loopHander = Dry_CH;
                                //大循环结束对每个箱子气体做拟合计算
                                //将每次测量按测量箱进行合并
                                string Index = "1";
                                for (int i = 0; i < chamberList.Count; i++)
                                {

                                    chamberList[i].updateFor4Loops(); // 调用每个箱子的updateFor4Loops方法，计算平均值和标准差
                                    Index = chamberList[i].caseindex.ToString();

                                    int year = chamberList[i].start_time.Year;
                                    int month = chamberList[i].start_time.Month;
                                    int day = chamberList[i].start_time.Day;
                                    int doy = chamberList[i].start_time.DayOfYear;
                                    int sod = (int)chamberList[i].start_time.TimeOfDay.TotalSeconds;
                                    string currentTime = chamberList[i].start_time.ToString("HH:mm:ss");
                                    string current_endTime = chamberList[i].end_time.ToString("HH:mm:ss");


                                    string CO2slope = chamberList[i].slope_co2.ToString();
                                    string H2Oslope = chamberList[i].slope_h2o.ToString();
                                    string CH4slope = chamberList[i].slope_ch4.ToString();
                                    string N2Oslope = chamberList[i].slope_n2o.ToString();
                                    string NH3_slope = chamberList[i].slope_nh3.ToString();

                                    // 检查外层字典是否包含 Index
                                    if (!Form1.Fit_Data.ContainsKey(Index))
                                    {
                                        // 如果不包含，则初始化内层字典并添加到外层字典
                                        Form1.Fit_Data[Index] = new Dictionary<string, string[]>();
                                    }

                                    // 添加 CO2slope
                                    AddValueToInnerDictionary(Form1.Fit_Data[Index], "CO2slope", CO2slope);

                                    // 添加 H2Oslope
                                    AddValueToInnerDictionary(Form1.Fit_Data[Index], "H2Oslope", H2Oslope);

                                    // 添加 CH4slope
                                    AddValueToInnerDictionary(Form1.Fit_Data[Index], "CH4slope", CH4slope);

                                    // 添加 N2Oslope
                                    AddValueToInnerDictionary(Form1.Fit_Data[Index], "N2Oslope", N2Oslope);

                                    // 添加 NH3_slope
                                    AddValueToInnerDictionary(Form1.Fit_Data[Index], "NH3_slope", NH3_slope);


                                    double AC = Math.Round(chamberList[i].Ac_Li, 2);
                                    double EC = Math.Round(chamberList[i].Ec_Li, 2);
                                    double MER = Math.Round(chamberList[i].MER_Li, 2);
                                    double N2OER = Math.Round(chamberList[i].N2OER_Li, 2);
                                    double NH3ER = Math.Round(chamberList[i].NH3ER_PI, 2);
                                    double ACR2 = Math.Round(chamberList[i].AcR2, 2);
                                    double ECR2 = Math.Round(chamberList[i].EcR2, 2);
                                    double MERR2 = Math.Round(chamberList[i].MerR2, 2);
                                    double N2OR2 = Math.Round(chamberList[i].N2oR2, 2);
                                    double ppfd_cov = Math.Round(chamberList[i].CvPPFD, 2);
                                    //获取该箱体中的平均数据
                                    CAPTS_Suite.DataLine avgdata = chamberList[i].get_avgData();
                                    double temperature = avgdata.temperature;
                                    double relative_humidity = avgdata.relative_humidity;
                                    double ppfd = avgdata.ppfd;
                                    double air_pressure = avgdata.air_pressure;
                                    double CO2 = avgdata.co2;
                                    double h2o = avgdata.h2o;
                                    double ch4 = avgdata.ch4;
                                    double n2o = avgdata.n2o;
                                    double nh3 = avgdata.nh3;

                                    double CO2_std = avgdata.co2_StdDev;
                                    double h2o_std = avgdata.h2o_StdDev;
                                    double ch4_std = avgdata.ch4_StdDev;
                                    double n2o_std = avgdata.h2o_StdDev;
                                    double nh3_std = avgdata.nh3_StdDev;

                                    string Epath_2 = @"E:\CAPTS_data\";
                                    string fitingfile = "";
                                    //保存数
                                    if (Directory.Exists(Epath_2))
                                    {
                                        fitingfile = @"E:\\CAPTS_data\" + _startTime.ToString("yyyyMMdd") + "cycle_fiting.csv";
                                    }
                                    else
                                    {
                                        fitingfile = @"D:\\CAPTS_data\" + _startTime.ToString("yyyyMMdd") + "cycle_fiting.csv";
                                    }
                                    string str2 = year.ToString() + "," + month.ToString() + "," + day.ToString() + "," + doy.ToString() + "," + sod.ToString() + "," + currentTime + "," + current_endTime + "," + "Chamber" + Index + "," + temperature.ToString() + "," + relative_humidity.ToString() + "," + ppfd.ToString() + "," + air_pressure.ToString() + "," + CO2.ToString() + "," + CO2_std.ToString() + "," + chamberList[i].slope_co2.ToString() + "," + chamberList[i].Ac_Li.ToString() + "," + ACR2.ToString() + "," + h2o.ToString() + "," + h2o_std.ToString() + "," + chamberList[i].slope_h2o.ToString() + "," + chamberList[i].Ec_Li.ToString() + "," + ECR2.ToString() + "," + ch4.ToString() + "," + ch4_std.ToString() + "," + chamberList[i].slope_ch4.ToString() + "," + chamberList[i].MER_Li.ToString() + "," + MERR2.ToString() + "," + n2o.ToString() + "," + n2o_std.ToString() + "," + chamberList[i].slope_n2o.ToString()
                                        + "," + chamberList[i].N2OER_Li.ToString() + "," + N2OR2.ToString() + "," + nh3.ToString() + "," + nh3_std.ToString() + "," + chamberList[i].slope_nh3.ToString() + "," + chamberList[i].NH3ER_PI.ToString() + "," + ppfd_cov.ToString();
                                    if (!File.Exists(fitingfile))
                                    {
                                        using (StreamWriter writer = File.CreateText(fitingfile))
                                        {
                                            writer.WriteLine("Year" + "," + "Month" + "," + "Day" + "," + "Doy" + "," + "Seconds" + "," + "Start_Time" + "," + "End_Time" + "," + "ChamberID" + "," + "temperature(oC)" + "," + "relative humidity(%)"
                    + "," + "PPFD(umol.m-2.s-1)" + "," + "air pressure(kPa)" + "," + "CO2_Mean(ppm)" + "," + "CO2_StdDev" + "," + "CO2 Slope" + "," + " Ac(umol.m-2 ground area.s-1)" + "," + "R2(AC)" + "," + "H2O_Mean(ppm)" + "," + "H2O_StdDev" + "," + "H2O Slope" + "," + "EC(umol.m-2 ground area.s-1)" + "," + "R2(EC)" + "," + "CH4_Mean(ppb)" + "," + "CH4_StdDev" + "," + "CH4 Slope" + "," + " MER(umol.m-2 ground area.s-1)" + "," + "R2(MER)" + "," + "N2O_Mean(ppb)" + "," + "N2O_StdDev" + "," + "N2O Slope" + "," + "N2OER(umol.m-2 ground area.s-1)" + "," + "R2(N2OER)" + "," + "NH3_Mean" + "," + "NH3_StdDev" + "," + "NH3 Slope" + "," + " NH3ER(umol.m-2 ground area.s-1)" + "," + "PPFD coefficient of variation (%)");
                                            writer.WriteLine(str2);
                                        }
                                        //Console.WriteLine("循环数据拟合第"+ key1+"测量箱数据已成功写入文件！");
                                    }
                                    else
                                    {
                                        using (StreamWriter writer = new StreamWriter(fitingfile, true))
                                        {
                                            writer.WriteLine(str2);
                                        }
                                        // Console.WriteLine("循环数据拟合第" + key1 + "测量箱数据已成功写入文件！");
                                    }
                                }
                                Form1.slope_time = Convert.ToDateTime(chamberList[0].get_goodDataList()[0].time_string);
                                omd.get_measurement_list().Clear(); //释放资源，接收下次数据
                                omd = new OneMeasurementData(caseNumber);
                                chamberList = omd.get_measurement_list();

                                // 当前这个测量循环结束了。等待进入下一次循环。
                            }

                        }
                        if (t3 == T3)
                        {
                            // 等待下一个循环时间到了，开始下一个循环，从第1次抽气开始，第1号箱子开始，
                            casein = 0; caseIndex = 1; currentLoop = 1;
                            t1 = 0; t2 = 0; t3 = 0;
                            loopHander = Start;
                            Measure_flag = true;
                        }

                        await Task.Delay(1000); 
                    }
                }
            }

        }

        //自定义测量箱顺序的measureLoop函数，重载
        public void measureLoop(object parameter,string seq,int num)
        {

            // 下面几行是原来的代码
            string value = (string)parameter;
            Pro_State = "measureLoop Run !!!";
            //获取测量箱顺序序列并约束其大小不超过测量箱数量
            //string[] sequence = seq.Split(';');
            string[] sequence = seq
                      .Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries)
                      .Where(s => !string.IsNullOrWhiteSpace(s))
                      .ToArray();//不要空格
            if (sequence.Length > caseNumber)
			{
                // 调整数组的大小为保留数量
                Array.Resize(ref sequence, caseNumber);
            }
            int[] chamberIDList = new int[sequence.Length];
			for (int k=0; k<sequence.Length; k++)
			{
				chamberIDList[k] = int.Parse(sequence[k]);

            }
            if (value.Equals("3"))
            {
                SBA5_Measure(parameter, chamberIDList);
            }
            else
            { measureLoop(parameter, chamberIDList); }



        }
        void AddValueToInnerDictionary(Dictionary<string, string[]> innerDictionary, string key, string value)
        {
            if (innerDictionary.ContainsKey(key))
            {
                // 如果内层字典中已存在该键，将新值添加到现有数组中
                var existingValues = innerDictionary[key].ToList();
                existingValues.Add(value);
                innerDictionary[key] = existingValues.ToArray();
            }
            else
            {
                // 如果内层字典中不存在该键，创建一个新数组并添加值
                innerDictionary[key] = new string[] { value };
            }
        }
        //校准函数
        public double calibrate(double x,string str)
        {
            double y = 0.0,a = 0.0,b = 0.0, c = 0.0 ,d= 0.0;
            using (StreamReader sr = new StreamReader(CAPTS_Borker.SysParameter))//需要加标定文件到指定文件夹
            {
                string line;

                // 从文件读取并显示行，直到文件的末尾 
                while ((line = sr.ReadLine()) != null)
                {
                    if (line.Contains(str + ":"))
                    {
                        string[] str1 = line.Split(':');
                        string[] str2 = str1[1].Split(',');
						a = double.Parse(str2[0]);
						b = double.Parse(str2[1]);
						c = double.Parse(str2[2]);
						d = double.Parse(str2[3]);
                    }
                    //Console.WriteLine(line);
                }

            }
            //A和D为零时主板传入的数据不需要校准,返回原值
            if (a == 0 ||  d == 0) 
			{ return x; }
			//进行校准
			else 
			{
                y = (a * x + b - c) / d;
			}
            return y;
        }

    }

    //Picarro仪器
    class CAPTS_Picarro : CAPTS_Borker
    {
        public static string PI_CO2 = "0";//PICARRO CO2
        public static string PI_CO2_dry = "0";//PICARRO CO2_dry
        public static string PI_H2O = "0";//PICARRO H2O
        public static string PI_N2O = "0";//PICARRO N2O
        public static string PI_N2O_dry = "0";//PICARRO N2O_dry
        public static string PI_CH4 = "0";//PICARRO CH4
        public static string PI_CH4_dry = "0";//PICARRO CH4_dry
        public static string PI_NH3 = "0";//PICARRO NH3
        private static System.Threading.Timer _timer;
        private static Socket _clientSocket;
        private static readonly string fullCommand = "_Meas_GetConc\r"; // 添加<CR>
        private static readonly byte[] commandBytes = Encoding.ASCII.GetBytes(fullCommand);
        public CAPTS_Picarro()
        {

        }
        public static async Task Handle_Received_Application_Message()
        {
            // 初始化套接字
            _clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            // 解析服务器的IP地址169.254.39.219
            IPAddress ipAddress = IPAddress.Parse("169.254.68.101");
            IPEndPoint ipEndpoint = new IPEndPoint(ipAddress, 51020);
            try
            {
                // 连接到服务器
                await _clientSocket.ConnectAsync(ipEndpoint);
                // 设置定时器，每隔0.5秒钟执行一次HandleReceivedApplicationMessage
                _timer = new System.Threading.Timer(async _ => await HandleReceivedApplicationMessage(), null, 0, 500);
                Console.WriteLine(" 连接服务器成功！");
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString() + " 连接服务器出错！五秒后重新尝试连接...");
                CleanUp();
                await Task.Delay(5000); // 等待5秒
                await Handle_Received_Application_Message(); // 重新启动该方法
            }
        }

        private static async Task HandleReceivedApplicationMessage()
        {
            try
            {
                if (_clientSocket.Connected)
                {
                    // 发送命令到服务器
                    await _clientSocket.SendAsync(new ArraySegment<byte>(commandBytes), SocketFlags.None);
                    // 创建缓冲区接收数据
                    byte[] buffer = new byte[1024 * 1024];
                    // 接收数据
                    int num = await _clientSocket.ReceiveAsync(new ArraySegment<byte>(buffer), SocketFlags.None);
                    // 处理接收到的数据
                    string response = Encoding.UTF8.GetString(buffer, 0, num);
                    getDataFormPicarro(response);
                    //Console.WriteLine(" 接收数据成功！");
                }
                else
                {
                    Console.WriteLine("Socket is not connected.");
                    CleanUp();
                }
            }
            catch (Exception ex)
            {
                //若发送命令出现问题不断开连接进行下一次命令发送
                Console.WriteLine(ex.ToString() + "发送命令到服务器出错，进行下一次命令发送！");
            }
        }
        /*
		//p还未联网获取测试
        //向服务器发送命令接口
        //调用格式SendCommandAndReceiveResponsecommand（"getxxx","2023","11","10"）
        //检索最新测量的气体浓度 SendCommandAndReceiveResponsecommand（"_Meas_GetConc"）
        //例如：“558.692；1.859；1.630<CR>”每个浓度值在小数点后用3个数字报告。多种气体浓度通过分号（；）。
        //返回值中没有单位指示。关于每个浓度的单位名称，请请参阅您的用户手册。
        public static async Task Handle_Received_Application_Message()
        {

            // 拼接命令和参数
            string fullCommand = "_Meas_GetConc\r"; // 添加<CR>
            // 将命令转换为ASCII格式
            byte[] commandBytes = Encoding.ASCII.GetBytes(fullCommand);
            // 创建一个套接字(Socket)对象，用于与服务器通信
            using (Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
            {
                // 解析服务器的IP地址
                IPAddress ipAddress = IPAddress.Parse("169.254.39.219"); // 初始化网络端点：包括待请求连接的IP地址和端口号
                IPEndPoint ipEndpoint = new IPEndPoint(ipAddress, 51020);
                try
                {
                    // 异步连接到服务器
                    await clientSocket.ConnectAsync(ipEndpoint);
                    // 异步发送命令到服务器
                    await clientSocket.SendAsync(new ArraySegment<byte>(commandBytes), SocketFlags.None);

                    // 创建缓冲区，用于接收从服务器传回的数据
                    byte[] buffer = new byte[1024 * 1024];

                    // 异步从服务器接收数据，并将其存储在缓冲区中
                    int num = await clientSocket.ReceiveAsync(new ArraySegment<byte>(buffer), SocketFlags.None);

                    // 返回数据
                    string response = Encoding.UTF8.GetString(buffer, 0, num);

                    // 处理从服务器接收到的数据
                    getDataFormPicarro(response);
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.ToString() + " 连接服务器出错！");
					CleanUp();
                }
                
            }
        }
		*/
        public static void CleanUp()
        {
            _timer?.Dispose();
            if (_clientSocket != null)
            {
                if (_clientSocket.Connected)
                {
                    _clientSocket.Shutdown(SocketShutdown.Both);
                }
                _clientSocket.Close();
            }
        }
        public static void getDataFormPicarro(string str)
        {
            //Picarro数据示例：0.000;0.000;0.334;0.334;0.351;0.351;0.350;1161.887;1162.374;2.303;2.304;0.024;202.576
            //共13个数据,以分割成数组为例;0,1数据都为0；第2，3分别为：N2O,N2O_dry（ppm）第4，5，6分别为;未知,N20_dry1min,N2O_dry5min
            //第7，8分别为：CO2，CO2_dry（ppm）第9，10分别为：CH4,CH4_dry（ppm）第11，12分别为：H2O（%），NH3（ppb）
            //Console.WriteLine("Picarro接收数据：" + str);
            string[] str1 = str.Split(';');
            PI_N2O = (Math.Round((Convert.ToDouble(str1[2])) * 1000, 2)).ToString();//ppm 将ppm转换成ppb：*1000
            PI_N2O_dry = (Math.Round((Convert.ToDouble(str1[3])) * 1000, 2)).ToString();
            PI_CO2 = (Math.Round((Convert.ToDouble(str1[7])), 2)).ToString();//ppm
            PI_CO2_dry = (Math.Round((Convert.ToDouble(str1[8])), 2)).ToString();
            PI_CH4 = (Math.Round((Convert.ToDouble(str1[9])) * 1000, 2)).ToString();//ppm 将ppm转换成ppb：*1000
            PI_CH4_dry = (Math.Round((Convert.ToDouble(str1[10])) * 1000, 2)).ToString();
            PI_H2O = ((Convert.ToDouble(str1[11])) * 10000).ToString();//%   将%转换成ppm：*10000
            PI_NH3 = (Math.Round((Convert.ToDouble(str1[12])), 2)).ToString();//ppb
        }



    }

    struct ChipPackages 
	{
		public static string C_CO2 ="0" ;//Chip CO2
		public static string C_H2O ="0" ;//Chip H2O
		public static string C_PPFD = "0";//Chip PPFD
		public static string C_PA ="0"; //Chip PA
		public static string C_T ="0";//Chip T
		public static string C_HR="0";//Chip HR
		public static string C_CO2_uV = "0";
		public static string C_H2O_uV ="0";
		public static string C_PPFD_uV = "0";
		public static string C_PA_uV = "0";
		public static string C_T_uV = "0";
		public static string C_HR_uV ="0";
		public static string C_FLOW = "0";
	}

}
